Skip to content

PyTube 下载长视频遇到 HTTP 400 错误的解决方案

问题描述

当使用 PyTube 库下载时长约 100 分钟的 YouTube 视频时,程序会抛出 HTTP Error 400: Bad Request 错误。这个问题通常发生在下载长视频时,而短视频下载正常。错误信息如下:

urllib.error.HTTPError: HTTP Error 400: Bad Request

问题特征

  • 七天内突然出现,之前工作正常
  • 影响长视频下载(约100分钟)
  • 升级 PyTube 和清除浏览器缓存无效
  • 根本原因:YouTube API 变更导致 PyTube 的请求格式过期

重现问题的代码示例

python
from pytube import YouTube

# 长视频URL会触发错误
youtubeObject = YouTube('https://www.youtube.com/watch?v=DASMWPUFFP4')
youtubeObject = youtubeObject.streams.get_highest_resolution()
youtubeObject.download('D:\\Utakmice')  # 抛出 HTTP 400 错误

推荐解决方案:使用 PyTubeFix 替代库

解决方案说明

PyTube 官方库可能响应不够及时,推荐使用 PyTubeFix — 这是一个积极维护的 PyTube 分支库,专门修复了此类兼容性问题。它保持与原 PyTube 相同的 API 接口,更换简单。

安装与使用

  1. 安装 PyTubeFix:

    bash
    pip install pytubefix
  2. 修改代码(仅需导入路径变化):

    python
    from pytubefix import YouTube
    from pytubefix.cli import on_progress  # 进度条支持(可选)
    
    url = "https://www.youtube.com/watch?v=DASMWPUFFP4"
    yt = YouTube(url, on_progress_callback=on_progress)  # 添加进度回调
    
    print(f"下载视频: {yt.title}")
    ys = yt.streams.get_highest_resolution()
    ys.download('D:\\Utakmice')  # 正常下载长视频

优势

  • 完全兼容原 PyTube 代码逻辑
  • 开发者持续跟进 YouTube API 变化
  • 无需修改底层库代码

注意事项

PyTubeFix 仓库地址:https://github.com/JuanBindez/pytubefix
若遇到新问题,建议查看该仓库的 Issue 板块获取最新解决方案。

备选方案:修改 PyTube 源码

如果必须使用原 PyTube 库,可通过修改其源码解决:

  1. 找到库中的 innertube.py 文件(路径通常为:Lib\site-packages\pytube\innertube.py

  2. 修改客户端参数:

    • 查找以下代码片段:
      python
      def __init__(self, client='ANDROID', use_oauth=False, allow_cache=True):
    • client='ANDROID' 改为:
      python
      def __init__(self, client='WEB', use_oauth=False, allow_cache=True):
  3. 保存修改后重新运行程序

注意

此方法存在局限:

  1. PyTube 升级后修改会被覆盖
  2. 不保证长期有效(依赖 YouTube API 行为)
  3. 推荐仅在临时场景使用

替代方案:使用 YouTube-DL 分支库

python
# 安装 yt-dlp(替代方案)
pip install yt-dlp
python
import yt_dlp

def download_video(url):
    ydl_opts = {}
    with yt_dlp.YoutubeDL(ydl_opts) as ydl:
        ydl.download([url])

video_url = input("输入YouTube视频URL: ")
download_video(video_url.strip())

错误原因分析

HTTP 400 错误本质是客户端请求格式错误。根本原因是:

  1. YouTube 更新了 API 接口
  2. PyTube 使用的请求参数(特别是 client='ANDROID')被标记为过期
  3. 服务器拒绝处理非法格式的请求
    POST -> /youtubei/v1/player?videoId=... (API版本过期)

总结建议

方案适用场景可持续性
PyTubeFix生产环境、长期维护⭐⭐⭐⭐⭐
修改源码临时测试、受限环境⭐⭐
yt-dlp需要更多高级功能⭐⭐⭐⭐

首选方案

python
# 使用 pytubefix 稳定版
from pytubefix import YouTube
YouTube("视频URL").streams.first().download()

YouTube API 变更频繁,建议关注相关 GitHub 仓库获取最新更新: