如何提取 B 站视频字幕
如何提取 B 站视频字幕
平时看视频的时候,觉得长的内容视频不适合我这种爱走神人士,所以打算把视频直接抽取字幕做成文档来读。部分视频本身已经有 AI 字幕,所以我的目标不是重新做语音识别,而是尽量直接拿到平台已有的字幕数据。
实际跑下来,流程并不复杂。记得拿你的cookie去请求视频即可。不带 Cookie 时,视频标题、BV 号、CID 这些基础信息可能都能拿到,但字幕列表会直接返回空。
下面简单记录一下实现思路:
先拿到b站分享的短链接 :https://b23.tv/xxxxxxx
它本质上是一个跳转地址。第一步要做的不是直接请求字幕,而是先跟随跳转,拿到真正的视频地址,也就是包含 BV 号的地址。
例如最终会变成类似:
https://www.bilibili.com/video/BVxxxxxxxxxx后面的接口请求基本都围绕这个 BV 号展开。
1.通过 BV 号拿到 cid
拿到 BV 号之后,需要先请求视频基础信息接口,拿到视频的 cid。
这里的 cid 很关键。B 站一个视频可能有多个分 P,每个分 P 都有自己的 cid。字幕并不是只按 BV 号关联,而是和具体分 P 的 cid 绑定。
BV 号 -> 视频信息 -> cid -> 字幕列表这一步通常不难,普通请求基本就能拿到视频标题、aid、cid 等信息。
2. 请求播放器信息,查看字幕列表
有了 bvid 和 cid 之后,就可以请求播放器信息接口。字幕列表一般会出现在返回数据里的 subtitle.subtitles 字段。
如果视频有字幕,里面通常会有类似这样的信息:
{
"lan": "ai-zh",
"lan_doc": "中文(自动生成)",
"subtitle_url": "//aisubtitle.hdslb.com/..."
}这里最重要的是 subtitle_url。它就是字幕 JSON 文件的地址。
不过实际测试时,最常见的情况是:接口能正常返回,但 subtitles 是空数组。
这时候不要急着判断视频没有字幕。很多时候只是因为请求没有带登录态。
3. 获取登录态 Cookie
B 站字幕接口对登录态比较敏感。尤其是 AI 字幕,不带 Cookie 时经常拿不到字幕列表。
解决方式很直接:登录 B 站后,F12从浏览器 Cookie 里取出 SESSDATA,请求接口时带上它。

博客或代码示例里千万不要写真实值,用占位符即可:
SESSDATA=<your_sessdata>更稳妥的做法是放到环境变量里,而不是写进脚本:
export BILIBILI_SESSDATA='<your_sessdata>'SESSDATA 本质上就是登录凭证。它不应该出现在公开文章、GitHub 仓库、截图或者日志里。如果不小心泄露,建议立刻退出登录或刷新登录状态。
4. 下载字幕 JSON
当字幕列表正常返回后,取其中的 subtitle_url 即可。
有个小细节:B 站返回的字幕地址有时是以 // 开头的协议相对地址,比如:
//aisubtitle.hdslb.com/xxx.json实际请求时补上 https: 就行:
https://aisubtitle.hdslb.com/xxx.json下载后的字幕文件通常是 JSON,核心内容在 body 里。每一条字幕大概包含三类信息:
{
"from": 1.23,
"to": 3.45,
"content": "大家好,欢迎回来"
}其中:
from:开始时间,单位是秒;to:结束时间,单位是秒;content:字幕文本。
到这里,真正的“提取字幕”其实就完成了。后面都是文本整理工作。
5. 导出两种结果:时间戳版和纯文本版
我一般会导出两份文件。
第一份是带时间戳的版本,方便回到视频里校对:
[00:00:01 - 00:00:03] 大家好,欢迎回来
[00:00:03 - 00:00:06] 今天我们来聊一个特别硬核的话题第二份是纯文本版本,拿ai整理一下,加工之后成为方便后续整理成文章、摘要或者朗读稿。这一步我觉得很重要
因为提取出来的AI 字幕通常会有几个问题:没有标点、分段很碎、专有名词容易错、同音词识别错误比较多。
比如技术视频里常见的情况:
cloud code -> Claude Code
绘画 -> 会话
sim link -> symlink这一步更像校稿,而不是重写。我的原则是:修正明显识别错误,补充必要标点,但尽量保留原视频的表达顺序和口语感。