使用Pytube下载YouTube视频时遇运行时错误求解决
问题解决:pytube下载YouTube视频时的RegexMatchError及HTTP 500错误
问题背景
要下载YouTube视频(示例链接:https://www.youtube.com/watch?v=_oHTzIsLMGc),使用以下pytube代码:
from pytube import YouTube # 输入视频链接 link = input("Enter the link of YouTube video you want to download: ") yt = YouTube(link) # 打印视频信息 print("Title: ",yt.title) print("Number of views: ",yt.views) print("Length of video: ",yt.length) print("Rating of video: ",yt.rating) # 获取最高分辨率流 y = yt.streams.get_highest_resolution() # 开始下载 print("Downloading...") y.download() print("Download completed!!")
运行时抛出pytube.exceptions.RegexMatchError: get_throttling_function_name: could not find match for multiple错误;使用pytube命令行工具时则出现urllib.error.HTTPError: HTTP Error 500: Internal Server Error。
错误原因
核心问题是pytube版本过旧,YouTube会定期更新视频流的签名验证逻辑和反爬机制,旧版本pytube中的正则表达式无法匹配新的JavaScript代码,导致签名解析失败;命令行的500错误也是因为签名生成错误,请求被YouTube服务器拒绝。
解决方法
1. 升级pytube到最新版本
卸载旧版本,安装官方最新版:
pip uninstall pytube -y pip install --upgrade pytube
如果官方版仍有问题,可安装GitHub上的开发分支(修复了最新适配问题):
pip install git+https://github.com/pytube/pytube.git
2. 手动修复正则表达式(临时方案,不推荐)
若无法升级,找到pytube安装目录下的cipher.py文件,修改get_throttling_function_name函数的正则匹配规则:
将原代码中的:
function_patterns = [ r'a\.[a-zA-Z]\s*&&\s*\([a-z]\s*=\s*a\.get\("n"\)\)\s*&&.*?\|\|\s*([a-z]+)', r'\([a-z]\s*=\s*([a-zA-Z0-9$]+)(\[\d+\])?\([a-z]\)', ]
替换为:
function_patterns = [ r'throttlingPlan\s*=\s*([a-zA-Z0-9$]+)\(', r'\.execute\s*\(\s*([a-zA-Z0-9$]+)\(', ]
保存后重启代码即可。
最小可行示例(MWE)
使用升级后的pytube,以下是稳定运行的最小下载代码:
from pytube import YouTube def download_youtube_video(url): try: yt = YouTube(url) # 获取最高分辨率的渐进式流(音视频合并) stream = yt.streams.get_highest_resolution() print(f"正在下载: {yt.title}") stream.download() print("下载完成!") except Exception as e: print(f"下载失败: {str(e)}") if __name__ == "__main__": video_url = input("输入YouTube视频链接: ") download_youtube_video(video_url)
如果需要下载播放列表,可使用以下代码:
from pytube import Playlist def download_playlist(url): try: pl = Playlist(url) print(f"正在下载播放列表: {pl.title}") for video in pl.videos: stream = video.streams.get_highest_resolution() print(f"正在下载: {video.title}") stream.download(output_path=pl.title) print("播放列表下载完成!") except Exception as e: print(f"播放列表下载失败: {str(e)}") if __name__ == "__main__": playlist_url = input("输入YouTube播放列表链接: ") download_playlist(playlist_url)
内容的提问来源于stack exchange,提问作者user2925716
相关产品推荐
相关产品推荐

