用 Python 抓取 YouTube:4 种真正可行的方法

最后更新于 April 15, 2026

如果你曾经试过 requests.get("https://www.youtube.com/..."),再用 BeautifulSoup 去解析视频标题,那你大概率已经体会过那种“打开一看全是空的 <div>,结果一个有用数据都没有”的无奈。

这几乎是开发者第一次尝试抓取 YouTube 时最常遇到的挫败感。YouTube 是一个单页应用(SPA)——几乎所有内容都通过 JavaScript 在客户端渲染。你的 Python 脚本拿到的 HTML 只是一个外壳,真正的视频标题、播放量和其他元数据,其实都藏在一个叫 ytInitialData 的巨大 JSON 里,页面加载后由 JS 注入进去。

所以,你那句看起来很合理的 soup.find("div", class_="ytd-video-renderer") 最终返回 None,并不是你写错了,而是因为这个元素在原始 HTTP 响应里根本不存在。一旦我搞清楚这一点,整个问题就豁然开朗了——下面这 4 种方法,都是我经过大量测试、踩坑、修复报错、翻看 GitHub issue 之后总结出来的。我会逐个讲清楚它们的适用场景,告诉你什么时候该用哪一种,最后还会给你一个无需写代码的捷径,适合只想拿到数据、不想搭环境的人。

为什么要用 Python 抓取 YouTube?

YouTube 不只是一个视频平台,它还是一个拥有 的数据源。平台上有 ,而且每分钟还在新增 的内容。对企业、研究人员和创作者来说,这些公开可见的信息都非常值得程序化分析。

问题在于,YouTube 自带的数据分析功能只能看到你自己频道的数据。如果你想研究竞品的更新频率、追踪某个细分领域的热门话题,或者分析别人的评论区情绪,就必须借助抓取。

我见过最常见的实际应用场景包括:

使用场景需要这些数据的人涉及的数据
竞品分析市场团队、内容策略人员播放量、发布频率、互动率
线索开发销售团队、B2B 外联频道联系信息、简介中的商务邮箱
市场调研产品经理、分析师热门话题、评论中的受众情绪
内容策略YouTuber、代理机构高表现形式、最佳标题/标签模式
SEO / 关键词研究SEO 专员视频标题、标签、描述、排名信号
品牌监测公关团队、品牌经理视频标题、评论、描述中的品牌提及
学术研究研究人员、数据科学家用于 情绪分析 的评论数据集(某项 2025 年研究对 4.5 万条 YouTube 评论进行 BERT 微调后,准确率达到 93.1%)

比如,一项关于 DJI、GoPro 和 Insta360 的竞品分析发现, ——这种洞察在 YouTube Studio 里是看不到的。

为什么单靠 requests + BeautifulSoup 抓不到 YouTube

在讲能用的方法之前,你得先明白为什么最直观的方案会失败。这不是纯理论问题,而是能帮你省下好几个小时的排错时间。

“看起来最简单”的思路大概是这样:

1import requests
2from bs4 import BeautifulSoup
3response = requests.get("https://www.youtube.com/@somechannel/videos")
4soup = BeautifulSoup(response.text, "html.parser")
5videos = soup.find_all("a", id="video-title-link")
6print(len(videos))  # 永远是 0

结果总是 0。正如 所说:“页面是动态加载的,而 requests 库不支持这种方式。” 说得更直接:“只靠 requests 和 BeautifulSoup,你无法执行 JavaScript。”

解释了背后的机制:YouTube 是单页应用(SPA)。当你发起普通 HTTP 请求时,只会拿到最初的 HTML 外壳,真正内容还没渲染。视频数据被藏在浏览器本来会执行的 JavaScript 对象里,然后再注入 DOM。

好消息是:YouTube 确实把你需要的所有数据都放进了原始 HTML,只不过不是 DOM 元素,而是藏在 <script> 标签里的两个 JSON 块中:

  • ytInitialData —— 页面结构、视频列表、互动指标、评论续加载 token
  • ytInitialPlayerResponse —— 核心视频元数据(标题、描述、时长、格式、字幕)

只要你知道怎么提取和解析,这两者都可以直接通过一次 requests.get() 拿到,不需要浏览器。这就是下面的第 1 种方法。

用 Python 抓取 YouTube 的 4 种方式:横向对比

在深入每种方法前,先看决策表。我测试过这 4 种方案,并按真实项目里最关键的标准做了比较。

对比维度requests + BS4(ytInitialData)Selenium / Playwrightyt-dlpYouTube Data API无代码(Thunderbit)
配置复杂度中(需要 API Key)
支持 JS 渲染部分支持(解析 JSON)支持支持不适用(结构化 API)支持
速度快(云端)
反爬风险已处理
配额 / 限速无(但可能被封 IP)无(但容易被识别)每天 10,000 units按额度计费
抓评论可行但复杂内置支持内置支持视页面而定
转录稿复杂支持
最适合快速抓元数据搜索结果、动态页面批量元数据 + 评论结构化大规模数据非程序员、快速导出

快速总结: youtube-scraping-methods.webp

你到底能从 YouTube 提取哪些数据?用哪种方法?

这是一张我刚开始做这类项目时最希望有人提前给我的参考表。没有任何一种方法能覆盖所有字段——这也是为什么这篇文章要讲 4 种方案。

数据字段BS4(ytInitialData)Selenium/Playwrightyt-dlpYouTube APIThunderbit
视频标题
播放量
点赞数⚠️ 不稳定
评论(文本)⚠️ 复杂⚠️
转录稿/字幕⚠️
标签⚠️
缩略图 URL
频道订阅数⚠️
上传日期
视频时长
Shorts 专属数据⚠️⚠️⚠️

具体选哪种方法,取决于你最需要表里的哪些字段。如果你需要评论和转录稿,yt-dlp 明显更强;如果你要的是结构化统计数据,且规模中等,API 是更稳妥的选择;如果你只想两分钟内拿到结果,继续往下看 Thunderbit 那一节。

extracted-data-categories.webp

方法 1:用 requests + BeautifulSoup 抓取 YouTube(解析 ytInitialData)

这个方法利用了 YouTube 会把页面数据以 JSON 形式嵌在原始 HTML 里的特点。你不需要浏览器,只需要知道去哪找。

  • 难度: 入门
  • 耗时: 约 15 分钟
  • 需要: Python 3.10+、requestsbeautifulsoup4

第 1 步:向 YouTube 页面发送 GET 请求

请带上一个真实一点的 User-Agent 请求头。默认的 python-requests/2.x 很容易被直接拦下—— 也证实,这通常是新手最容易踩的坑。

1import requests
2HEADERS = {
3    "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) "
4                  "AppleWebKit/537.36 (KHTML, like Gecko) "
5                  "Chrome/114.0.0.0 Safari/537.36",
6    "Accept-Language": "en-US,en;q=0.9",
7    "Cookie": "CONSENT=YES+cb",  # 绕过欧盟同意弹窗
8}
9url = "https://www.youtube.com/@mkbhd/videos"
10response = requests.get(url, headers=HEADERS)
11print(response.status_code)  # 应该是 200

CONSENT cookie 很关键——没有它,来自欧盟地区的请求通常会被重定向到 consent.youtube.com,而那里返回的 HTML 里根本没有 ytInitialData

第 2 步:解析 HTML,定位 ytInitialData 脚本

可以用 BeautifulSoup 或正则表达式找到包含 var ytInitialData =<script> 标签:

1import re
2import json
3# 提取 ytInitialData JSON
4match = re.search(
5    r"var ytInitialData\s*=\s*({.*?});</script>",
6    response.text,
7    re.DOTALL
8)
9if match:
10    data = json.loads(match.group(1))
11    print("ytInitialData 提取成功")
12else:
13    print("未找到 ytInitialData —— 请检查请求头 / cookie")

一个常见错误是用非贪婪的 .*?,然后只把 }; 当作结束符。因为 JSON 内部会频繁出现嵌套对象结束符,这样很容易提前截断。像 那样,最好用 };</script> 作为结束标记——这通常就是它所在脚本块里的最后一个赋值语句。

第 3 步:遍历 JSON 结构,提取视频数据

这个 JSON 层级很深。与其写死路径、等 YouTube 一改结构就全崩,不如用递归方式搜索 key(这类变动其实很常见—— 记录了 2023 年以来多次格式变更):

1def search_dict(partial, search_key):
2    stack = [partial]
3    while stack:
4        cur = stack.pop()
5        if isinstance(cur, dict):
6            for k, v in cur.items():
7                if k == search_key:
8                    yield v
9                else:
10                    stack.append(v)
11        elif isinstance(cur, list):
12            stack.extend(cur)
13# 从频道页面提取视频信息
14videos = []
15for vr in search_dict(data, "videoRenderer"):
16    videos.append({
17        "video_id": vr.get("videoId"),
18        "title": vr["title"]["runs"][0]["text"],
19        "views": vr.get("viewCountText", {}).get("simpleText", "N/A"),
20        "published": vr.get("publishedTimeText", {}).get("simpleText", "N/A"),
21    })
22print(f"找到 {len(videos)} 个视频")
23for v in videos[:5]:
24    print(f"  {v['title']}{v['views']}")

这种递归搜索方式,也是 、yt-dlp 和 Scrapfly 最后都采用的思路——因为它能扛住 YouTube 频繁的 JSON 结构调整。

第 4 步:把抓到的数据导出到 CSV 或 Excel

1import csv
2with open("youtube_videos.csv", "w", newline="", encoding="utf-8") as f:
3    writer = csv.DictWriter(f, fieldnames=["video_id", "title", "views", "published"])
4    writer.writeheader()
5    writer.writerows(videos)
6print("数据已导出到 youtube_videos.csv")

什么时候适合用这种方法,什么时候不适合

适合: 快速从少量频道页或视频页提取元数据;轻量级 SEO 工具;只需要标题、播放量、上传日期的一次性分析。

局限: JSON 结构会变——已知的改动包括点赞按钮重构(2023:toggleButtonRenderersegmentedLikeDislikeButtonViewModel)、描述重构(2023:description.runs[]attributedDescription.content)、频道 Videos 标签页重设计(2022–2023:gridRendererrichGridRenderer)。数据中心 IP 通常在 50–200 次请求后就会被软封。无法拿到评论,也没有转录稿。

方法 2:用 Selenium 或 Playwright 抓取 YouTube

当你需要和页面交互——比如滚动搜索结果、点击标签页、展开描述——浏览器自动化就是更合适的方案。

  • 难度: 中级
  • 耗时: 约 30 分钟
  • 需要: Python 3.10+、Playwright(pip install playwright && playwright install)或 Selenium + ChromeDriver

新项目我更推荐 Playwright,而不是 Selenium。 显示,Playwright 在单次操作速度上大约快 ;而 Selenium 通过 WebDriver-over-HTTP 工作,每条命令都多一层转换。

第 1 步:安装 Playwright

1pip install playwright
2playwright install chromium
1from playwright.sync_api import sync_playwright
2pw = sync_playwright().start()
3browser = pw.chromium.launch(headless=False)  # 显示浏览器窗口更不容易被识别
4context = browser.new_context()
5# 预置 consent cookie,绕过欧盟提示页
6context.add_cookies([{
7    "name": "SOCS",
8    "value": "CAISNQgDEitib3FfaWRlbnRpdHlmcm9udGVuZHVpc2VydmVyXzIwMjMwODI5LjA3X3AxGgJlbiACGgYIgJnPpwY",
9    "domain": ".youtube.com",
10    "path": "/",
11}])
12page = context.new_page()

第 2 步:打开 YouTube 页面并等待内容加载完成

1page.goto("https://www.youtube.com/@mkbhd/videos")
2page.wait_for_selector("a#video-title-link", timeout=15000)
3print("页面已加载 —— 视频元素已出现")

如果你抓的是搜索结果页,把 URL 换成 https://www.youtube.com/results?search_query=你的关键词 即可。

第 3 步:处理无限滚动,加载更多视频

YouTube 的频道页和搜索结果页都使用无限滚动。下面是经典的 scrollHeight 循环,改编自

1prev_height = -1
2max_scrolls = 20  # 记得设置上限,不然 1 万条视频的频道会一直滚
3scroll_count = 0
4while scroll_count &lt; max_scrolls:
5    page.evaluate("window.scrollTo(0, document.body.scrollHeight)")
6    page.wait_for_timeout(1500)  # 等待新内容加载
7    new_height = page.evaluate("document.body.scrollHeight")
8    if new_height == prev_height:
9        break  # 没有新内容加载出来
10    prev_height = new_height
11    scroll_count += 1
12print(f"已滚动 {scroll_count} 次")

第 4 步:从渲染后的页面提取视频数据

1video_elements = page.query_selector_all("a#video-title-link")
2videos = []
3for el in video_elements:
4    title = el.inner_text()
5    href = el.get_attribute("href")
6    video_id = href.split("v=")[-1] if href else None
7    videos.append({"title": title, "video_id": video_id, "url": f"https://www.youtube.com{href}"})
8print(f"提取到 {len(videos)} 个视频")

如果你还想拿播放量和上传日期,就需要继续抓取相邻元素。 提醒过,id="video-title-link" 并不是所有页面都通用——YouTube 的页面版本很多。更稳妥的兜底选择是 a[href*="watch"]

第 5 步:导出到 CSV 或 Google Sheets

1import csv
2with open("youtube_playwright.csv", "w", newline="", encoding="utf-8") as f:
3    writer = csv.DictWriter(f, fieldnames=["title", "video_id", "url"])
4    writer.writeheader()
5    writer.writerows(videos)
6browser.close()
7pw.stop()

什么时候适合用这种方法,什么时候不适合

适合: 抓搜索结果、交互式动态页面(点击标签、展开描述)、任何需要完整 DOM 的场景。

局限: 速度慢(按“滚动 + 提取”的流程,每条视频大约要 1.5–3 秒)。反爬识别风险高——原生 Selenium 会设置 navigator.webdriver === true,这类信号会被 。资源消耗大(每个浏览器实例大约占用 200–500 MB 内存)。如果要抓 100 个视频,耗时通常是 3–8 分钟,而用 yt-dlp 可能只要几秒。

方法 3:用 yt-dlp 抓取 YouTube

yt-dlp 可以说是 YouTube 抓取界的瑞士军刀。它是 youtube-dl 的社区分支,拥有 ,持续 nightly 更新,内置支持元数据、评论、转录稿和批量抓取,而且不需要浏览器或 API Key。

  • 难度: 入门到中级
  • 耗时: 约 10 分钟
  • 需要: Python 3.10+、pip install yt-dlp

第 1 步:安装 yt-dlp

1pip install yt-dlp

不需要浏览器驱动,不需要 API Key,也不需要配置文件。

第 2 步:不下载视频,只提取元数据

1import yt_dlp
2opts = {
3    "quiet": True,
4    "skip_download": True,      # 不下载视频,只要元数据
5    "no_warnings": True,
6}
7with yt_dlp.YoutubeDL(opts) as ydl:
8    info = ydl.extract_info(
9        "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
10        download=False
11    )
12print(f"标题: {info['title']}")
13print(f"播放量: {info['view_count']:,}")
14print(f"点赞: {info.get('like_count', 'N/A')}")
15print(f"时长: {info['duration']} 秒")
16print(f"上传日期: {info['upload_date']}")
17print(f"频道: {info['channel']}{info.get('channel_follower_count', 'N/A')} 订阅)")
18print(f"标签: {info.get('tags', [])[:5]}")

一次 extract_info 调用通常会返回 80–120 个字段,具体取决于视频状态:idtitlechannelchannel_idchannel_follower_countview_countlike_countcomment_countupload_datedurationtagscategoriesdescriptionthumbnailsis_liveavailabilityautomatic_captionssubtitleschaptersheatmap 等等。

第 3 步:提取 YouTube 视频评论

1opts = {
2    "quiet": True,
3    "skip_download": True,
4    "getcomments": True,
5    "extractor_args": {
6        "youtube": {
7            "max_comments": ["200", "50", "50", "10"],  # 总数、父评论、每条回复数、回复总数
8            "comment_sort": ["top"],
9        }
10    },
11}
12with yt_dlp.YoutubeDL(opts) as ydl:
13    info = ydl.extract_info(
14        "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
15        download=False
16    )
17comments = info.get("comments", [])
18print(f"抓到 {len(comments)} 条评论")
19for c in comments[:3]:
20    print(f"  [{c.get('like_count', 0)} 赞] {c['author']}: {c['text'][:80]}...")

评论抓取速度并不快。 提到评论抓取只有大约 30 KB/s——一条有 10 万评论的视频,抓完可能要几个小时。 还记录过一种情况:在评论分页还没结束前,格式 URL 就过期了(大约 6 小时)。如果视频评论很多,max_comments 一定要设置得更激进些。

第 4 步:提取转录稿和字幕

YouTube Data API 和 BS4 解析都拿不到完整转录稿,这正是 yt-dlp 的独特优势。

1opts = {
2    "quiet": True,
3    "skip_download": True,
4    "writesubtitles": True,
5    "writeautomaticsub": True,
6    "subtitleslangs": ["en", "en-orig"],
7    "subtitlesformat": "json3",   # 适合机器解析:包含毫秒级 start/dur 和文本
8    "outtmpl": "%(id)s.%(ext)s",
9}
10with yt_dlp.YoutubeDL(opts) as ydl:
11    info = ydl.extract_info(
12        "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
13        download=False
14    )
15# 直接从 info 字典读取字幕数据
16auto_captions = info.get("automatic_captions", {})
17manual_subs = info.get("subtitles", {})
18print(f"自动字幕语言: {list(auto_captions.keys())[:10]}")
19print(f"手动字幕语言: {list(manual_subs.keys())}")

json3 格式更适合机器解析——每个片段都有 start / dur 毫秒时间和文本内容。语言代码采用 BCP-47 规范(如 enen-USzh-Hansjaes)。

第 5 步:批量抓取多个视频或整个频道

1opts = {
2    "quiet": True,
3    "skip_download": True,
4    "extract_flat": "in_playlist",  # 快速模式:只取视频 ID 和标题
5    "sleep_interval": 2,
6    "max_sleep_interval": 6,
7}
8with yt_dlp.YoutubeDL(opts) as ydl:
9    info = ydl.extract_info(
10        "https://www.youtube.com/@mkbhd/videos",
11        download=False
12    )
13entries = info.get("entries", [])
14print(f"频道里找到 {len(entries)} 个视频")
15for e in entries[:5]:
16    print(f"  {e.get('title', 'N/A')}{e.get('id')}")

不管你传的是频道 URL、播放列表 URL,甚至是搜索语句(例如 ytsearch10:python scraping),yt-dlp 都能在内部帮你处理分页。

什么时候适合用这种方法,什么时候不适合

适合: 批量提取元数据、评论、转录稿、下载视频、抓整个频道且需要完整字段集。

局限: 不太适合抓搜索结果页(这类场景 Selenium/Playwright 更合适)。2024–2026 的反爬攻防让 yt-dlp 在规模化运行时更复杂了——YouTube 现在对某些客户端强制执行 。如果用于生产环境,建议安装 插件,并配合 --cookies-from-browser chrome 使用(最好用一个临时账号——yt-dlp 团队提醒,真实 Google 账号的 cookies 可能导致账号被封)。

方法 4:用 YouTube Data API 抓取 YouTube

官方的 YouTube Data API v3 是获取 YouTube 数据最稳定、最结构化的方式。返回的是干净的 JSON,字段文档齐全,而且没有反爬博弈。但很多教程都会忽略一个关键问题:配额机制

  • 难度: 中级
  • 耗时: 约 20 分钟(包含 API Key 设置)
  • 需要: Python 3.10+、Google Cloud 项目、pip install google-api-python-client

第 1 步:获取 YouTube Data API Key

  1. 打开
  2. 新建项目,或者选择已有项目
  3. 进入 APIs & Services → Library,搜索 “YouTube Data API v3”,然后点击 Enable
  4. 进入 APIs & Services → Credentials,点击 Create Credentials → API Key
  5. 复制这个 Key,后面代码里会用到

第 2 步:发起第一次 API 调用

1from googleapiclient.discovery import build
2API_KEY = "YOUR_API_KEY_HERE"
3youtube = build("youtube", "v3", developerKey=API_KEY)
4# 获取某个视频的详细信息
5response = youtube.videos().list(
6    part="snippet,statistics,contentDetails",
7    id="dQw4w9WgXcQ"
8).execute()
9video = response["items"][0]
10print(f"标题: {video['snippet']['title']}")
11print(f"播放量: {video['statistics']['viewCount']}")
12print(f"点赞: {video['statistics'].get('likeCount', '隐藏')}")
13print(f"评论: {video['statistics'].get('commentCount', '已关闭')}")
14print(f"时长: {video['contentDetails']['duration']}")
15print(f"标签: {video['snippet'].get('tags', [])[:5]}")

返回结果干净、结构明确、字段也有文档说明,基本不需要做 JSON 考古。

第 3 步:提取视频详情、频道信息和评论

1# 搜索视频
2search_response = youtube.search().list(
3    part="snippet",
4    q="python web scraping tutorial",
5    type="video",
6    maxResults=10,
7    order="viewCount"
8).execute()
9for item in search_response["items"]:
10    print(f"  {item['snippet']['title']}{item['id']['videoId']}")
11# 获取评论
12comments_response = youtube.commentThreads().list(
13    part="snippet",
14    videoId="dQw4w9WgXcQ",
15    maxResults=20,
16    order="relevance"
17).execute()
18for item in comments_response["items"]:
19    comment = item["snippet"]["topLevelComment"]["snippet"]
20    print(f"  [{comment['likeCount']} 赞] {comment['authorDisplayName']}: {comment['textDisplay'][:80]}")

YouTube API 配额现实情况(很多人不会告诉你)

这一部分最能区分“有用指南”和“复制粘贴教程”。默认配额是 ,按太平洋时间午夜重置。每个调用的消耗如下:

API 端点单次调用配额消耗单次最多结果数
search.list100 units50 条结果
videos.list1 unit50 个视频 ID(可批量)
channels.list1 unit50 个频道 ID
commentThreads.list1 unit100 条评论
captions.list50 units不适用

算一笔账。假设你想抓取 1,000 条搜索结果:

  • 搜索调用: 1,000 条结果 ÷ 每页 50 条 = 20 次调用 × 100 units = 2,000 units(一天预算的 20%,一下子就没了)
  • 这 1,000 条视频的详情: 1,000 个 ID ÷ 每批 50 个 = 20 次调用 × 1 unit = 20 units(很便宜,批量 videos.list 是救命稻草)
  • 这 1,000 条视频的评论(假设每条只抓 1 页):1,000 次调用 × 1 unit = 1,000 units

总计:一个不算大的抓取任务就要消耗大约 3,020 units。可如果这些视频的评论区很深(每条 50+ 页),剩下的 7,000 units 很快就会被耗光。一个有 50,000 条评论的视频,大概需要 500 页,也就是 500 units。你要是一天抓 20 个这种视频,配额就直接用完了。

需要完整的合规审核:隐私政策链接、服务条款链接、应用操作演示视频、以及配额计算说明。社区反馈显示,Google 一般 3–5 个工作日会有初步回复,但完整批准可能要几周甚至几个月,而且很多申请都会被拒,尤其是那种“我只是想拿更多数据做分析”的用途。

什么时候用 API: 中小规模、需要结构化且可靠的数据、评论和频道统计很重要、可以接受配额上限时。

什么时候更适合抓取: 大规模项目(每天 >10K 视频)、API 不暴露的字段(完整转录稿——captions.download 需要 OAuth 和视频拥有者权限),或者你需要每次查询超过 500 条搜索结果(即便 totalResults 说得再多,API 也硬性限制)。

无代码捷径:用 Thunderbit 抓 YouTube(无需 Python)

如果你是为了搭建数据管道,那就用上面 1–4 种方法。但如果你只是想在 2 分钟内拿到 YouTube 数据——比如营销人员要看竞品数据,或者开发者只是临时拉一份数据,不想搭项目环境——那还有更快的方式。

是我们专门为“写代码太重”的场景做的 AI 网页爬虫 Chrome 扩展,它可以直接在浏览器里的 YouTube 页面上工作。

3 步完成 YouTube 抓取

第 1 步: 安装 ,打开 YouTube 频道页、搜索结果页或视频页。

第 2 步: 在 Thunderbit 侧边栏点击 “AI 建议字段”。AI 会识别页面,并自动建议列名,比如视频标题、播放量、上传日期、时长、频道名和缩略图 URL。你可以按需增删或重命名列。

第 3 步: 点击 “抓取”,然后导出到 Google Sheets、Excel、CSV、Airtable 或 Notion。数据会以干净表格的形式直接呈现,拿来就能用。

适合谁

  • 营销人员:需要竞品频道数据,但不会写代码
  • 开发者:想快速拿一份数据,不想先搭虚拟环境和装依赖
  • 任何被反爬墙拦住的人 —— Thunderbit 直接在用户自己登录的浏览器会话里抓取,会继承你的 cookies 和 PO tokens,这能绕开很多服务器端爬虫常见的拦截问题
  • Thunderbit 还支持 ,可以继续访问每个视频页,并补充更多字段(点赞数、描述、标签等)

如果你想更深入了解 Thunderbit 在 YouTube 场景下的具体表现,可以看看

用 Python 抓 YouTube 时,如何避免被封

下面这些建议适用于所有 4 种 Python 方法。YouTube 的反爬机制在 ,主要依赖 3 类信号:IP 行为分析、JavaScript 执行要求,以及频繁变化的 HTML 结构。

适用于所有方法:

  • 轮换 User-Agent,并且连同完整请求头一起轮换——AcceptAccept-LanguageSec-CH-UA 这些 client hints 都要和声明的 UA 保持一致。 有最新列表。
  • 每次请求之间加入 2–8 秒的随机延迟。固定间隔本身就是一个识别信号。
  • 只要不是抓少量页面,就尽量使用住宅代理。数据中心 IP(AWS、GCP、Hetzner)在 了。
  • 会话和 IP 要一起轮换——YouTube 会把会话和 IP 绑定,同一个 session cookie 出现在两个 IP 上,会非常可疑。

针对 requests + BS4: 设置 CONSENT=YES+cb cookie。没有它,来自欧盟地区的请求会跳到同意页,那里没有任何数据。

针对 Selenium/Playwright: 在 Linux 服务器上用 xvfb 以有界面模式运行,不要直接用 --headless=new——无头 Chrome 仍会泄露足够多的指纹特征,供高级检测识别。可以考虑 ,它提供大约 17 种规避手段。

针对 yt-dlp: 使用 sleep_intervalmax_sleep_interval 选项。安装 插件来生成 PO Token。再配合 --cookies-from-browser chrome,但最好用临时账号。

针对 API: 通过 监控配额使用情况,并尽量批量请求。一个包含 50 个逗号分隔 ID 的 videos.list 调用只消耗 1 unit——要充分利用。

针对 Thunderbit: 因为抓取是在你的浏览器会话里完成的,所以反爬措施会自动被处理。你本质上是在自动化你原本手动会做的操作。

用 Python 抓 YouTube 合法吗?

这要看你抓什么、怎么抓,以及你如何使用这些数据。

2024 年的法律环境发生了变化,Meta Platforms v. Bright Data(加州北区,2024 年 1 月)中, 。在这项裁决之后,抓取公开可访问的数据风险明显降低。另一方面,hiQ v. LinkedIn 最终以 告终,原因包括违反 ToS、CFAA 违规(使用假账号)以及侵害动产——还附带永久禁令。

YouTube 自己的 说得很明确:除非事先获得书面许可,或法律允许,否则“不得使用任何自动化方式(例如机器人、botnet 或爬虫)访问服务”。官方认可的数据访问方式就是 YouTube Data API。

几个实操上的原则:

  • 抓取公开可见数据用于个人研究或非商业分析,通常风险相对更低
  • API 是最稳妥的路径,因为它是明确授权的
  • 不要抓取私有或登录受限内容,不要下载受版权保护的视频再二次分发,也不要因为评论中的个人信息而违反 GDPR
  • YouTube 评论在 GDPR 第 4(1) 条下属于个人数据——处理欧盟数据主体信息时要格外小心
  • 商业抓取项目请先咨询法律顾问

以上内容都不是法律建议。这个领域变化很快——一波新的 的案件,正因为这些公司抓取 YouTube 训练数据,而在 2025–2026 年持续重塑规则。

用 Python 抓 YouTube,应该选哪种方法?

决策建议如下:

  • 只想从少量页面快速拿元数据? → 方法 1(requests + BS4)。速度快、轻量,除了 requestsbeautifulsoup4 基本没别的依赖。
  • 需要抓搜索结果或操作动态页面? → 方法 2(Selenium/Playwright)。可以完整渲染浏览器,支持无限滚动,但速度慢,也更容易被识别。
  • 需要批量元数据、评论或转录稿? → 方法 3(yt-dlp)。单工具能力最强,难怪有
  • 需要中等规模下稳定、结构化的数据? → 方法 4(YouTube Data API)。官方、干净,但受 限制。
  • 想在 2 分钟内拿数据,不写代码?。基于浏览器,AI 驱动,点几下就能导出到 Google Sheets。

没有一种方法能覆盖所有场景。建议把上面的对比表和可提取字段表收藏起来,它们会在你下一个项目里帮你省很多时间。如果你还想了解更多 ,Thunderbit 博客里还有很多指南,涵盖从 的各种内容。

试试 Thunderbit 抓取 YouTube

常见问题

不用 API Key 也能抓 YouTube 吗?

可以。方法 1(requests + BS4)、方法 2(Selenium/Playwright)和方法 3(yt-dlp)都不需要 API Key。只有方法 4(YouTube Data API)需要。Thunderbit 也不需要任何 API Key——它直接在你的浏览器里抓取。

用 Python 抓 YouTube,最快的方法是什么?

如果只看 Python,yt-dlp 和 requests + BS4 速度最快——它们都不需要浏览器开销,基本可以按“每个视频几秒”拿到元数据。yt-dlp 尤其适合批量任务,因为它会在内部处理分页。对于不用 Python 的人来说,Thunderbit 是整体最快的,因为完全不用搭环境。

如何用 Python 抓 YouTube 评论?

yt-dlp 自带评论提取,使用 getcomments 选项是最简单的方式。YouTube Data API 也支持评论,通过 commentThreads.list 即可获取(每次 1 个配额单位,每页最多 100 条评论)。Selenium/Playwright 当然也能做,但需要滚动并抓取渲染后的评论元素,速度慢,而且很脆弱。

可以用 Python 抓 YouTube Shorts 吗?

可以。yt-dlp 对 Shorts 元数据支持很好——它会把 Shorts 当作普通视频处理,只是额外带有一些 Shorts 专属字段。YouTube Data API 也有部分支持(Shorts 的播放量统计在 有过变化——现在只要发生播放开始或重播都会计入)。BS4 和 Selenium/Playwright 对 Shorts 的支持相对有限,因为 Shorts 区块使用了不同的 DOM 结构。

一天能抓多少个 YouTube 视频?

如果用 YouTube Data API,你的上限大约是每天 10,000 quota units。若使用批量 videos.list 调用(每次 1 unit,最多 50 个 ID),理论上最多可以查 500,000 次视频统计信息;但 search.list 每次 100 units,很快就把预算吃光。用抓取方案(BS4、Selenium、yt-dlp)时,限制不是硬编码的,而是实践上的:通常每个 IP 每天几百到几千次请求后就可能触发封禁,具体取决于代理配置和请求模式。Thunderbit 则采用与你 绑定的额度系统。

了解更多

Ke
Ke
CTO @ Thunderbit. Ke is the person everyone pings when data gets messy. He's spent his career turning tedious, repetitive work into quiet little automations that just run. If you've ever wished a spreadsheet could fill itself in, Ke has probably already built the thing that does it.
目录

试试 Thunderbit

只需 2 次点击即可抓取线索和其他数据。AI 驱动。

获取 Thunderbit 免费使用
使用 AI 提取数据
轻松将数据传输到 Google Sheets、Airtable 或 Notion
Chrome Store Rating
PRODUCT HUNT#1 Product of the Week