# 几百个 YouTube 视频的字幕怎么批量下载？

> 批量下载 500 或 5,000 个 YouTube 视频的字幕而不被 429 拦住：视频 ID 从哪来，一个能断点续跑的 Python 脚本，以及整批跑完花多少钱。

网页版：https://okdata.online/zh/answers/bulk-youtube-transcripts/

**简短回答：**把视频 ID 列成清单，开几个并发逐个调用 YouTube 视频字幕接口；和 YouTube 打交道的是 okdata，你这边没有 IP 会被封。每份字幕 $0.004，1,000 个视频最多 $4.00，没有字幕的视频不收费。

一位做传播研究的老师手里有一张 800 个讲座视频的表格，想在周五前把字幕都放进一个文件。用 youtube-transcript-api 跑，几十个视频之后就报 429 Too Many Requests，大家加的重试逻辑又往往对着同一个 IP 继续猛发。这种规模的批量任务要准备好三样东西：一份干净的 ID 清单，一个懂得退让的客户端，以及断点续跑。

## 第一步：拿到 ID 清单

- **手里已经有链接。** 取 `v=` 后面的值，或者 `youtu.be/`、`/shorts/` 后面那一段。字幕接口要的是 11 位视频 ID。
- **手里只有一个主题。** [YouTube 视频搜索](/zh/apis/youtube/videos/search/)每页返回约 20 个视频，带播放量和频道，凑 100 个候选花 $0.02。
- **手里有一个频道。** 官方 Data API 对频道的上传列表调用 `playlistItems.list`，每页最多 50 个视频，只消耗 1 个配额单位，列出整个频道这样最省。

## 第二步：能续跑的脚本

```python
import json, os, time, requests
from concurrent.futures import ThreadPoolExecutor

URL = "https://api.okdata.online/v1/youtube/videos/transcript/get"
KEY = os.environ["OKDATA_API_KEY"]
OUT = "transcripts.jsonl"

def fetch(vid):
    while True:
        r = requests.get(URL, params={"id": vid}, timeout=90, headers={
            "Authorization": f"Bearer {KEY}", "Idempotency-Key": f"transcript-{vid}"})
        body = r.json()
        if body["code"] == "rate_limited":
            time.sleep(body.get("retry_after_seconds") or 2)
            continue
        return vid, body

ids = [line.strip() for line in open("video_ids.txt") if line.strip()]
done = {json.loads(l)["video_id"] for l in open(OUT)} if os.path.exists(OUT) else set()

with ThreadPoolExecutor(max_workers=4) as pool, open(OUT, "a", encoding="utf-8") as out:
    for vid, body in pool.map(fetch, [i for i in ids if i not in done]):
        if body["code"] == "ok":
            out.write(json.dumps(body["data"]["item"], ensure_ascii=False) + "\n")
        else:
            print(vid, body["code"])  # not_found 表示没有字幕，不扣费
```

中途崩了就再跑一遍，已经拿到的视频会跳过。带上 `Idempotency-Key` 之后，24 小时内重试一个其实已经成功的请求，会直接返回原结果，不会扣两次钱。

## 整批要花多少

| 批量 | 最多花费 |
|---|---|
| 100 个视频 | $0.40 |
| 800 个视频 | $3.20 |
| 1,000 个视频 | $4.00 |

没有字幕的视频和出错的请求都不收费，实际账单只会更低。新 key 自带 0.10 的额度，够先拿一小部分视频把脚本跑通。

## 限制

- 4 个并发是比较稳妥的起点。key 的突发上限写在 `X-RateLimit-Limit` 响应头里，`rate_limited` 不扣费。
- 不做语音转文字，没有字幕的视频要对你有权使用的音频跑 Whisper。
- 每次调用只返回一种语言，以响应里的 `lang` 为准。

## 什么情况换个做法

量小、偶尔跑一次的，在家里的网络上用 youtube-transcript-api，每次调用之间停一停，通常能跑完。自己频道的视频，用官方 API 直接下载字幕文件。从搜索到摘要的完整流程，见[视频转文字方案](/zh/solutions/transcripts/)。

## 用到的接口

- [YouTube 视频字幕](https://okdata.online/zh/apis/youtube/videos/transcript/get/) `youtube.videos.transcript.get`：$0.004/次
- [YouTube 视频搜索](https://okdata.online/zh/apis/youtube/videos/search/) `youtube.videos.search`：$0.004/次 · 每页约 20 条视频

更新于 2026-11-12
