批量下载 B站字幕:限流排查与「假残缺」识别实战

# 批量下载 B站字幕:限流排查与「假残缺」识别实战 > 摘要:批量下载 127 个视频的 B站 AI 字幕,最坑的不是接口,而是"看起来缺字幕"。本文拆解两个高频坑:限流导致字幕 URL 为空、以及"假残缺"——字幕轨道明明存在,却只能拉到几条。给出完整的识别方法和重试策略,读完可直接复现。 ## 背景 拿到 UP 主视频列表(见系列前一篇)后,下一步是批量下载字幕。B站字幕获取链路是:`view` 接口拿 cid → `player/v2` 拿字幕列表 → 下载字幕 JSON。链路不复杂,但**批量**场景下风控和限流会让成功率暴跌——最迷惑的是:字幕明明存在,下载下来却只有几条。 ## 正文 ### 1. 字幕获取链路 ```python # 1. view 接口: bvid -> cid d = session.get('https://api.bilibili.com/x/web-interface/view', params={'bvid': bvid}).json() cid = d['data']['cid'] # 2. player/v2: 拿字幕列表 d2 = session.get('https://api.bilibili.com/x/player/v2', params={'bvid': bvid, 'cid': cid}).json() subs = d2['data']['subtitle']['subtitles'] # [{lan, lan_doc, subtitle_url}, ...] # 3. 下载字幕 JSON (body 数组 -> SRT) r = session.get(subtitle_url).json() for item in r['body']: # item: {from, to, content} ``` 三个关键点: - **必须带登录 cookie(SESSDATA)**:匿名请求 `player/v2` 返回的字幕列表为空 - **优先选中文轨道**:`lan` 以 `zh` 开头的(`ai-zh`/`zh-Hans`),其次再选其它 - **`subtitle_url` 是带 `auth_key` 的临时地址**,有时效 ### 2. 限流症状与识别 批量下载时的两个典型症状: | 症状 | 现象 | 原因 | |------|------|------| | URL 为空 | `subtitle_url` 是空字符串 | B站对高频请求的降级响应 | | 内容为空 | URL 有效但 JSON 无 `body` | 同上,降级到空内容 | 识别方法:**单个视频单独请求一次**,对比轨道列表和条数。如果单独请求能拿到几百条,批量时只有几条——这就是限流,不是视频本身缺字幕。 ### 3. "假残缺":本次实战最深的坑 下载 128 个视频后做质量检查,发现 14 个视频字幕条数异常少(1~43 条)。按直觉会判断"这些视频字幕不完整"。 但单独复查轨道后发现: ``` BV12RYTzeEBy | 下载时 6 条 | 单独请求 373 条 BV1XYq9Y6E4y | 下载时 6 条 | 单独请求 581 条 BV1E6vzBwE2M | 下载时 9 条 | 单独请求 731 条 ``` **结论:批量下载时 B站返回了截断/部分内容,单独请求才是完整数据。** 这就是"假残缺"——不是视频没字幕,是批量场景下被限流喂了部分数据。 诊断方法: ```python # 对条数异常的 srt 做二次核验: 单独请求轨道并统计 body 条数 r = session.get(subtitle_url).json() n = len(r.get('body') or []) # 对比现有 srt 的 ' --> ' 出现次数 ``` ### 4. 重试策略(实战有效) 针对限流,最终采用的重试策略: - 每个视频最多尝试 12 次,**间隔递增**(`8s + attempt * 3s`) - URL 为空 → 等待后**重新请求 player/v2**(拿新 URL,旧 URL 可能已失效) - 内容为空 → 等待后重新下载(部分返回的数据不能直接用) - 条数异常的 srt 单独重跑,直到条数与单独请求一致 ```python for attempt in range(12): # 拿轨道 -> 若 url 空: sleep(8 + attempt*3); continue # 下载 -> 若 body 空: sleep(8 + attempt*3); continue # 成功则 break ``` 实测效果:首批 24/32 成功率,重试后 128 个视频全部拿到完整字幕(其中 127 个走 B站字幕,1 个走转写兜底,见系列第三篇)。 ## 踩坑记录 1. **不要对"条数少"直接下结论**——先单独请求核验,区分"真残缺"(轨道不存在)和"假残缺"(限流部分返回) 2. **限流是递增惩罚**:连续高频请求会越来越严,间隔要递增而不是固定 3. **字幕 URL 要每次重取**:缓存的 URL 可能已过期或指向降级内容 ## 总结 - 批量下载字幕的正确姿势:带 cookie → 选中文轨道 → 限流递增重试 - "假残缺"是最容易误判的坑:**轨道列表完整 ≠ 下载内容完整**,务必核验 body 条数 - 质量检查不能只看"文件存在",要看条数是否合理 下一步:遇到视频真的没有字幕轨道怎么办?音频转写兜底方案见系列第三篇。
posted @ 2026-08-15 10:53  劉均年  阅读(4)  评论(0)    收藏  举报