yt-dlp:突破极限

yt-dlp支持数千个网站——不只是YouTube——并添加了关键改进:更智能的格式排序、SponsorBlock集成、多线程片段下载和干净的Python嵌入API。

yt-dlp:突破极限
微信 ezpoda免费咨询:AI编程 | AI模型微调| AI私有化部署
AI模型价格对比 | AI工具导航 | ONNX模型库 | Tripo 3D | Meshy AI | ElevenLabs | KlingAI | ArtSpace | Phot.AI | InVideo

yt-dlp是现已停滞的youtube-dl的社区维护分支,目前在GitHub上拥有149k+星标1,500+贡献者

它支持数千个网站——不只是YouTube——并添加了关键改进:更智能的格式排序、SponsorBlock集成、多线程片段下载和干净的Python嵌入API。如果你在2026年仍在使用youtube-dlpytube,你正在浪费性能和可靠性。

1、安装yt-dlp及其依赖

yt-dlp需要 Python 3.10+并强烈推荐ffmpeg用于合并独立的视频/音频流。

pip install "yt-dlp[default]"

[default]额外安装会引入certifibrotliwebsocketsrequestspycryptodomex——这些都是稳定下载所需的。要绕过某些网站的TLS指纹识别,添加curl-cffi

pip install "yt-dlp[default,curl-cffi]"

单独安装ffmpeg(不要安装名为ffmpeg的Python包——那是不同的东西):

# macOS
brew install ffmpeg
# Ubuntu/Debian
sudo apt install ffmpeg

2、在Python中嵌入yt-dlp:基础

yt-dlp通过YoutubeDL类暴露干净的Python API。你传入选项字典并调用.download()

import yt_dlp
# Basic download - best quality, auto-merged
ydl_opts = {
    'format': 'bestvideo+bestaudio/best',
    'merge_output_format': 'mp4',
    'outtmpl': '%(title)s [%(id)s].%(ext)s',  # default naming template
}
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
    ydl.download(['https://www.youtube.com/watch?v=BaW_jenozKc'])

with块确保下载器上下文被正确清理。始终使用它。

3、格式选择:精确获取你想要的

yt-dlp的格式选择器是其最强大的功能之一。默认值(bv*+ba/b)选择最佳视频流并与最佳音频合并——但你可以更精确。

ydl_opts = {
    # Best video up to 1080p, paired with best audio
    'format': 'bestvideo[height<=1080]+bestaudio/best[height<=1080]',
    'merge_output_format': 'mp4',
}

对于仅音频提取(例如播客归档、音乐):

ydl_opts = {
    'format': 'm4a/bestaudio/best',
    'postprocessors': [{
        'key': 'FFmpegExtractAudio',
        'preferredcodec': 'mp3',
        'preferredquality': '192',
    }],
    'outtmpl': '%(uploader)s - %(title)s.%(ext)s',
}

4、不下载提取元数据

有时你只需要视频信息——标题、时长、可用格式、上传日期。使用extract_info配合download=False

import json
import yt_dlp
URL = 'https://www.youtube.com/watch?v=BaW_jenozKc'
with yt_dlp.YoutubeDL({}) as ydl:
    info = ydl.extract_info(URL, download=False)
    # sanitize_info makes the dict JSON-serializable
    clean = ydl.sanitize_info(info)
print(f"Title: {clean['title']}")
print(f"Duration: {clean['duration']}s")
print(f"Uploader: {clean['uploader']}")
print(f"Views: {clean['view_count']:,}")

5、真正的问题:速率限制和地理限制

大多数教程在这里停止——而真实世界的使用变得困难。

问题一——速率限制。 YouTube等平台检测来自同一IP的重复请求并进行节流或阻止。在规模上,单个IP很快就会达到限制。

问题二——地理限制。 大量视频内容被区域锁定。yt-dlp内置的--xff头欺骗在某些情况下有帮助,但不可靠且容易被检测。

诚实的答案是:头欺骗不能替代实际通过目标区域的真实IP路由。 平台已经变得擅长检测这种不匹配。

6、代理解决方案:yt-dlp如何处理代理

yt-dlp有一流的代理支持。proxy选项接受HTTP、HTTPS或SOCKS5 URL:

ydl_opts = {
    'proxy': 'http://user:password@proxy-host:port',
    # For geo-verification only (some sites require this):
    'geo_verification_proxy': 'http://user:password@proxy-host:port',
}

还有专门的geo_verification_proxy选项——该代理专门用于验证地理限制站点的IP位置,而实际下载流量可以通过不同的路由。

6.1 为什么用住宅代理?

代理的好坏取决于其背后的IP。核心权衡如下:

代理类型 检测风险 速度 地理精度
免费/公共 很高
数据中心 中高 有限
住宅 精确
ISP(静态住宅) 很快 精确

免费代理在这种用例中是死路。 它们被过度使用,被每个主要平台标记,且不可靠。

住宅代理通过真实消费者设备——真实的家庭、真实的ISP——路由你的流量。从YouTube的角度看,请求看起来与从该位置浏览的普通用户完全相同。

6.2 使用yt-dlp设置Bright Data住宅代理

代理URL格式:

http://brd-customer-[CUSTOMER_ID]-zone-residential:[PASSWORD]@brd.superproxy.io:33335

6.3 地理定向下载:访问区域锁定内容

要在用户名中使用国家代码参数来定向特定国家的IP:

# Route through a US residential IP
PROXY_URL = (
    f"http://brd-customer-{BD_CUSTOMER_ID}-zone-residential-country-us:"
    f"{BD_PASSWORD}@brd.superproxy.io:33335"
)

用户名中的-country-us后缀告诉Bright Data通过美国住宅IP路由你的请求。你可以用任何ISO 3166-1 alpha-2国家代码替换us

6.4 生产就绪的批量下载器带代理轮换

这是一个更完整的脚本——你在生产中实际使用的那种。它处理多个URL、失败重试、添加日志,并按下载轮换国家定向代理:

import yt_dlp
import logging
import time
from pathlib import Path

BD_CUSTOMER_ID = "your_customer_id"
BD_PASSWORD = "your_password"
OUTPUT_DIR = Path("downloads")
OUTPUT_DIR.mkdir(exist_ok=True)
TARGET_COUNTRIES = ["us", "gb", "de", "fr", "au"]

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s [%(levelname)s] %(message)s"
)
logger = logging.getLogger(__name__)

def get_proxy_url(country: str) -> str:
    return (
        f"http://brd-customer-{BD_CUSTOMER_ID}"
        f"-zone-residential-country-{country}:"
        f"{BD_PASSWORD}@brd.superproxy.io:33335"
    )

def build_ydl_opts(proxy_url: str) -> dict:
    return {
        "format": "bestvideo[height<=1080]+bestaudio/best",
        "merge_output_format": "mp4",
        "proxy": proxy_url,
        "geo_verification_proxy": proxy_url,
        "outtmpl": str(OUTPUT_DIR / "%(uploader)s - %(title)s [%(id)s].%(ext)s"),
        "retries": 5,
        "fragment_retries": 5,
        "ignoreerrors": False,
        "quiet": False,
        "no_warnings": False,
        "sleep_interval": 2,
        "max_sleep_interval": 5,
    }

def download_with_retry(url: str, max_retries: int = 3) -> bool:
    for attempt, country in enumerate(TARGET_COUNTRIES[:max_retries]):
        proxy_url = get_proxy_url(country)
        logger.info(f"Attempt {attempt + 1}/{max_retries} - proxy country: {country.upper()}")
        try:
            with yt_dlp.YoutubeDL(build_ydl_opts(proxy_url)) as ydl:
                error_code = ydl.download([url])
                if error_code == 0:
                    logger.info(f"✓ Successfully downloaded: {url}")
                    return True
                else:
                    logger.warning(f"Download returned error code {error_code}")
        except yt_dlp.utils.DownloadError as e:
            logger.error(f"DownloadError on attempt {attempt + 1}: {e}")
            time.sleep(2 ** attempt)  # exponential backoff
    logger.error(f"✗ All retries exhausted for: {url}")
    return False

def batch_download(urls: list[str]) -> dict[str, bool]:
    results = {}
    for i, url in enumerate(urls, 1):
        logger.info(f"[{i}/{len(urls)}] Processing: {url}")
        results[url] = download_with_retry(url)
        time.sleep(1)
    return results

if __name__ == "__main__":
    VIDEO_URLS = [
        "https://www.youtube.com/watch?v=BaW_jenozKc",
    ]
    results = batch_download(VIDEO_URLS)
    print("\n--- Download Summary ---")
    for url, success in results.items():
        status = "✓ OK" if success else "✗ FAILED"
        print(f"{status}: {url}")

6.5 ISP代理:长时间会话的替代方案

如果你的用例涉及下载超长视频或在整个播放列表中维护稳定会话(IP在会话中途轮换可能导致问题),考虑Bright Data的ISP代理

ISP代理是静态住宅IP——它们与真实ISP关联,不会轮换,除非你明确请求新的。这给了你住宅IP的合法性加上数据中心代理的稳定性。

6.6 处理年龄限制内容的Cookie

一些内容需要身份验证。yt-dlp可以直接从你的浏览器加载cookie:

ydl_opts = {
    'format': 'best',
    'proxy': PROXY_URL,
    'cookiesfrombrowser': ('chrome', None, None, None),
}

cookiesfrombrowser选项接受(browser, keyring, profile, container)元组——None使用默认值。这让yt-dlp以你已登录的浏览器会话身份验证,无需手动管理cookie。

7、结束语

yt-dlp是2026年Python程序化视频下载的正确工具——在站点支持和可靠性方面没有其他工具接近。

yt-dlp中的 proxy选项是你需要的全部,用于通过任何代理路由流量——不需要特殊库。

免费代理会失败。 住宅代理——来自真实设备上真实ISP的IP——是大规模访问地理限制或速率限制内容的唯一可靠解决方案。

当你需要稳定、非轮换的IP时使用ISP代理(例如长播放列表下载)。

始终在生产中添加带指数退避的重试逻辑请求之间的休眠间隔


原文链接: Supercharge yt-dlp with Python

汇智网翻译整理,转载请标明出处