问答

yt-dlp 提示要登录确认不是机器人,不用 Cookie 怎么拿 YouTube 字幕?

简短回答

只要文字和数据的话,干脆别下载:YouTube 视频字幕接口返回带时间戳的字幕,$0.004;YouTube 视频详情返回标题、简介、标签、播放和点赞,$0.004。不用 Cookie,不用登录账号,请求也不从你服务器的 IP 发出。

一个每晚跑的任务,在 VPS 上执行 yt-dlp --write-auto-subs --skip-download,给研究语料收字幕。某天早上,所有视频都报 Sign in to confirm you're not a bot。常见的解法是加 --cookies-from-browser,可 yt-dlp 的维护者自己都讨论过,要提醒用户这些 Cookie 对应的账号可能被封。为了拿字幕把一个真实的 Google 账号押上去,不划算。

大多数字幕任务其实用不到视频文件,要的只是文字和几项视频信息,这两样都不用下载就能拿到。

yt-dlp 的输出分别用什么替代

yt-dlp 给的 换成 价格
.vtt / .srt 字幕 YouTube 视频字幕 $0.004
title、description、tags、view_count、like_count、duration YouTube 视频详情 $0.004
两样都要,100 个视频 200 次调用 {{cost:youtube.videos.get100+youtube.videos.transcript.get100}}

视频详情里,标签放在 hashtags 字段。加 view=full 能拿到 ext.duration_ms 时长。

请求发到 okdata,你的 VPS 不再直接访问 YouTube,所以你这边不会再碰到人机验证,也不用维护 Cookie 和代理。上游偶尔出问题时返回 upstream_failed,不扣费,隔一会儿重试即可;24 小时内带同一个 Idempotency-Key 重试,也不会重复收费。

照 yt-dlp 的样子写出 .vtt 文件

import os, requests

API = "https://api.okdata.online/v1"
H = {"Authorization": f"Bearer {os.environ['OKDATA_API_KEY']}"}

def ts(sec):
    ms = int(round(sec * 1000))
    return f"{ms // 3_600_000:02}:{ms // 60_000 % 60:02}:{ms // 1000 % 60:02}.{ms % 1000:03}"

def save_vtt(video_id, lang="en"):
    body = requests.get(f"{API}/youtube/videos/transcript/get", headers=H,
                        params={"id": video_id, "lang": lang}, timeout=60).json()
    if body["code"] != "ok":
        print(video_id, body["code"])  # not_found 表示没有字幕,不扣费
        return
    t = body["data"]["item"]
    cues = [f"{ts(s['start'])} --> {ts(s['end'])}\n{s['text']}" for s in t["segments"]]
    with open(f"{video_id}.{t['lang']}.vtt", "w", encoding="utf-8") as f:
        f.write("WEBVTT\n\n" + "\n\n".join(cues) + "\n")

save_vtt("dQw4w9WgXcQ")

放弃了什么

  • 拿不到媒体文件。任务要的是视频或音频本身,这条路替代不了 yt-dlp。
  • 每次调用返回一条字幕轨,视频有你指定的 lang 就优先给那种语言,以返回的 lang 为准。
  • 不区分作者上传的字幕和自动字幕。
  • 没有字幕的视频返回 not_found,不扣费;这里不做语音转文字。
  • 这个接口只收 id,不收链接。

哪些时候还是 yt-dlp 合适

  • 必须要媒体文件。换到家里的网络上跑 yt-dlp,或者接受 Cookie 的风险,用一个小号。
  • 量小、偶尔跑,从住宅 IP 发请求一般能通过验证。
  • 自己频道的字幕,从 YouTube Studio 或官方 Data API 拿就行,视频本来就是你的。

整批视频的做法和费用见视频转文字方案。

更新于