Tkinter回调两类异常求助:单首音乐与播放列表下载报错
解决Pytube+Tkinter下载器的两个回调异常问题
一、单首音乐下载的RegexMatchError错误
错误原因
- 输入链接为空或不符合YouTube视频链接规范,导致pytube的正则无法提取11位视频ID
- 旧版本pytube的正则表达式不兼容YouTube新链接格式(如短链接、带额外参数的链接)
修复方案
- 先验证输入链接非空且符合格式
- 升级pytube到最新版本:
pip install --upgrade pytube - 在下载逻辑中添加异常捕获,避免程序崩溃
二、播放列表下载的KeyError: 'list'错误
错误原因
- 输入的不是播放列表链接(缺少
list=参数),pytube无法解析播放列表ID - 输入为空,导致解析逻辑直接失败
修复方案
- 验证输入链接必须包含
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()
关键修复点
- 输入验证:添加非空检查和正则格式验证,提前拦截无效输入
- 异常捕获:所有下载逻辑包裹在
try-except中,错误信息通过弹窗提示用户 - 窗口管理:改用
Toplevel创建子窗口,保留主窗口避免无法返回 - 路径处理:创建文件夹前判断是否存在,处理标题中的非法字符
- 下载优化:播放列表直接下载到目标文件夹,无需事后移动文件
内容的提问来源于stack exchange,提问作者KELLER
相关产品推荐
相关产品推荐

