You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Tkinter回调两类异常求助:单首音乐与播放列表下载报错

解决Pytube+Tkinter下载器的两个回调异常问题

一、单首音乐下载的RegexMatchError错误

错误原因

  1. 输入链接为空或不符合YouTube视频链接规范,导致pytube的正则无法提取11位视频ID
  2. 旧版本pytube的正则表达式不兼容YouTube新链接格式(如短链接、带额外参数的链接)

修复方案

  • 先验证输入链接非空且符合格式
  • 升级pytube到最新版本:pip install --upgrade pytube
  • 在下载逻辑中添加异常捕获,避免程序崩溃

二、播放列表下载的KeyError: 'list'错误

错误原因

  1. 输入的不是播放列表链接(缺少list=参数),pytube无法解析播放列表ID
  2. 输入为空,导致解析逻辑直接失败

修复方案

  • 验证输入链接必须包含list=字段且非空
  • 添加异常捕获处理非法链接情况

三、代码其他问题及完整修复版

原代码还存在依赖缺失、文件夹创建未判重、窗口管理混乱等问题,以下是修复后的完整代码:

from pytube import YouTube, Playlist
import os
import tkinter as tk
from tkinter import messagebox, StringVar, Label, Button, Entry
import re

def window1():
    intro = Label(root1, text="Welcome", font=("Times New Roman", 14))
    intro.grid(row=1, column=1)
    intro2 = Label(root1, text="Music or Playlist", font=("Times New Roman", 14))
    intro2.grid(row=2, column=1)

    buttonm = Button(root1, text="Music", command=open_music_window, width=20, font=("Times New Roman", 12))
    buttonm.grid(row=3, column=1)

    buttonp = Button(root1, text="Playlist", command=open_playlist_window, width=20, font=("Times New Roman", 12))
    buttonp.grid(row=4, column=1)

def open_music_window():
    music_window = tk.Toplevel(root1)
    music_window.title("Single Music Downloader")
    music_window.geometry("600x150")

    linkmusic = Label(music_window, text="YouTube Video Link", font=("Times New Roman", 12))
    linkmusic.grid(row=1, column=0, padx=5, pady=5)
    link_text = Entry(music_window, width=50, textvariable=linkvideo)
    link_text.grid(row=1, column=1, pady=5, padx=5, columnspan=2)

    buttondownload = Button(music_window, text="Download", command=download_single_music, width=20, font=("Times New Roman", 12))
    buttondownload.grid(row=3, column=1, padx=3, pady=3)

def download_single_music():
    folder = os.path.dirname(__file__)
    youtube_link = linkvideo.get().strip()

    if not youtube_link:
        messagebox.showerror("Error", "Please enter a valid YouTube link")
        return
    video_pattern = re.compile(r'(https?://)?(www\.)?(youtube\.com/watch\?v=|youtu\.be/)[0-9A-Za-z_-]{11}')
    if not video_pattern.match(youtube_link):
        messagebox.showerror("Error", "Invalid YouTube video link")
        return

    try:
        yt = YouTube(youtube_link)
        ys = yt.streams.get_by_itag(251)
        if not ys:
            messagebox.showerror("Error", "No valid audio stream found")
            return
        ys.download(folder)
        messagebox.showinfo("Success", f"Downloaded: {yt.title}")
    except Exception as e:
        messagebox.showerror("Download Error", str(e))

def open_playlist_window():
    playlist_window = tk.Toplevel(root1)
    playlist_window.title("Playlist Downloader")
    playlist_window.geometry("600x150")

    linkplaylist = Label(playlist_window, text="YouTube Playlist Link", font=("Times New Roman", 12))
    linkplaylist.grid(row=1, column=0, padx=5, pady=5)
    link_text = Entry(playlist_window, width=50, textvariable=linkplay)
    link_text.grid(row=1, column=1, pady=5, padx=5, columnspan=2)

    button2download = Button(playlist_window, text="Download", command=download_playlist, width=20, font=("Times New Roman", 12))
    button2download.grid(row=3, column=1, padx=3, pady=3)

def download_playlist():
    folder = os.path.dirname(__file__)
    youtube_playlist = linkplay.get().strip()

    if not youtube_playlist:
        messagebox.showerror("Error", "Please enter a valid playlist link")
        return
    if 'list=' not in youtube_playlist:
        messagebox.showerror("Error", "Invalid playlist link (missing 'list=' parameter)")
        return

    try:
        pl = Playlist(youtube_playlist)
        safe_title = re.sub(r'[\\/*?:"<>|]', "", pl.title)
        directory = os.path.join(folder, safe_title)
        if not os.path.exists(directory):
            os.makedirs(directory)

        for video in pl.videos:
            ys = video.streams.get_by_itag(251)
            if ys:
                ys.download(directory)
        messagebox.showinfo("Success", f"Playlist downloaded to:\n{directory}")
    except Exception as e:
        messagebox.showerror("Download Error", str(e))

if __name__ == "__main__":
    root1 = tk.Tk()
    root1.geometry("600x400")
    root1.title("YouTube Downloader")
    linkvideo = StringVar()
    linkplay = StringVar()
    window1()
    root1.mainloop()

关键修复点

  1. 输入验证:添加非空检查和正则格式验证,提前拦截无效输入
  2. 异常捕获:所有下载逻辑包裹在try-except中,错误信息通过弹窗提示用户
  3. 窗口管理:改用Toplevel创建子窗口,保留主窗口避免无法返回
  4. 路径处理:创建文件夹前判断是否存在,处理标题中的非法字符
  5. 下载优化:播放列表直接下载到目标文件夹,无需事后移动文件

内容的提问来源于stack exchange,提问作者KELLER

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 09:15:32