把 B站 视频内容(元数据 / 字幕 / 全量评论)蒸馏为 OKF (Open Knowledge Format) Bundle——视频知识萃取,不是单纯评论采集。
"不原封不动全爬,而是找到有价值的内容" —— 确定性蒸馏(全量评论去重去空、字幕带时间轴)+ OKF 结构化输出;再由 Claude 会话做两层提炼:①
references/content-distill.md把字幕压缩成视频内容知识文档(创作者主张)②references/discussion-distill.md从评论提炼讨论观点(受众反应,赞数≠价值,语义聚类)。无 CC 字幕时走 ASR 补字幕。模糊需求(非具体 BV 号)可先用search子命令召回候选再采集。
| 依赖 | 版本 | 说明 |
|---|---|---|
| Python | ≥ 3.10 | |
| ffmpeg | 最新 | 系统依赖,apt install ffmpeg / brew install ffmpeg |
| PyYAML | ≥ 6.0 | |
| bilibili-api-python | ≥ 17.0 | |
| funasr | ≥ 1.1 | ASR 可选依赖 |
| bertopic | ≥ 0.16 | 聚类可选依赖 |
# 1. 克隆仓库
git clone https://github.com/021gink/bili2okf.git
cd bili2okf
# 2. 创建虚拟环境(推荐)
python3 -m venv .venv
source .venv/bin/activate # Linux/macOS
# 或 .venv\Scripts\activate # Windows
# 3. 安装依赖
pip install -r requirements.txt
# 4. 确保 ffmpeg 已安装
# Ubuntu/WSL: apt install ffmpeg
# macOS: brew install ffmpeg
# Windows: 下载 ffmpeg 并添加到 PATH
⚠️ 运行目录与 Python:在 bili2okf 的父目录执行,且用 .venv 的 python(source bili2okf/.venv/bin/activate后用python,或直接bili2okf/.venv/bin/python)—— ASR 的 funasr/yt-dlp 装在 venv,系统 python3 跑 ASR 会报No module named 'funasr'。
# 1. 首次登录:终端打印二维码 → 用 B站 APP 扫码
cd ..
bili2okf/.venv/bin/python -m bili2okf --login
# 2. 采集视频(以下命令均在 bili2okf 父目录、用 .venv 的 python)
bili2okf/.venv/bin/python -m bili2okf BV1GJ411x7h7
# 3. 指定输出目录
bili2okf/.venv/bin/python -m bili2okf BV1xxxxxx --out my_bundle/
# 3b. 只采评论(字幕/评论解耦,不跑字幕/ASR)
bili2okf/.venv/bin/python -m bili2okf BV1xxxxxx --only comments
# 4. 模糊搜索视频
bili2okf/.venv/bin/python -m bili2okf search "LLM agent 架构" --top 5
# 5. 查看帮助
bili2okf/.venv/bin/python -m bili2okf --help登录是自动的:终端 ASCII 二维码 → B站 APP 扫码 → 自动拿到 SESSDATA(不要求手动从浏览器复制 cookie)。SESSDATA 持久化到 ~/.bili2okf/session.json(0600 权限),半年有效,过期再扫一次。
okf_bundle/
├── index.md # 自动生成(okf_version: "0.1")
├── videos/{bvid}.md # type: Bilibili Video(元数据/互动数据/简介)
├── transcripts/{bvid}.md # type: Transcript(字幕全文带时间轴;有 CC 字幕时,无字幕待 ASR)
├── comments/{bvid}.md # type: Comment Digest(全量评论原料,赞数≠价值,待提炼)
├── content/{bvid}.md # ⚠ 采集层不生成——由 Claude 读 references/content-distill.md 从字幕提炼后写入
├── insights/{bvid}.md # ⚠ 采集层不生成——由 Claude 读 references/discussion-distill.md 提炼评论观点后写入
└── log.md # 采集历史
每个 Concept 符合 OKF v0.1(YAML frontmatter + 非空 type)。用验证器确认(脚本在 tools/,非仓库根):
bili2okf/.venv/bin/python bili2okf/tools/okf_validate.py okf_bundle/ --strict
# → conformant (OKF v0.1): YES / ✓ clean — no errors or warnings.| 数据 | 免登录 | 说明 |
|---|---|---|
| 视频元数据(标题/简介/封面/互动数据) | ✅ | view 接口 |
| 字幕(CC 字幕全文) | ✅ | 仅当视频有公开 CC 字幕;无字幕/版权锁定视频跳过 |
| ASR 补字幕(无 CC 字幕时) | ✅ 可选依赖 | bili2okf/asr.py:yt-dlp 取音频 + FunASR SenseVoiceSmall 转写(fsmn-vad + SenseVoiceSmall + ct-punc),rich_transcription_postprocess 清洗标签,生成带时间轴 transcript,再走 content-distill。装 requirements.txt(含 funasr)+ 系统 ffmpeg;--no-asr 可禁用 |
| 视频搜索(模糊需求找视频) | ✅ | bili2okf search.py:bilibili-api.search 免登录召回候选(综合/播放/最新排序),空 bvid 已过滤;结果不进 Bundle,配合 references/search-distill.md 重排选最契合 |
| 全量评论 | 扫码登录后(--login)采全量;不登录只采免认证的首页样本 |
| 原子 | 决策 | 复用对象 |
|---|---|---|
| OKF 序列化 + index 生成 | 直接复用 | 官方 okf_lib.py(patelisii/OKF-Claude-Code) |
| B站 登录认证(QR + 持久化) | 集成 | bilibili-api QrCodeLogin + Credential |
| 全量评论采集 | 集成 | bilibili-api get_comments_lazy(offset 链表分页) |
| 蒸馏(去重 / 去空 / 时间轴) | 自建 | 确定性规则,不调 LLM,不按赞预筛 |
| 视频内容提炼(字幕→知识文档) | 会话内 | references/content-distill.md(基于字幕事实 + 时间轴 + blockquote 溯源) |
| 讨论观点提炼(聚类 / 提炼) | 会话内 | references/discussion-distill.md(LLM 语义聚类 + 赞数≠价值);评论 >1000 可选 tools/cluster_comments.py(BERTopic 预处理,核心模块化为 bili2okf/topics.py,venv 装 requirements.txt) |
| 视频搜索(模糊需求→最契合视频) | 混合 | bili2okf search.py(确定性召回,免登录)+ references/search-distill.md(会话内重排,契合度>热度) |
为何集成 bilibili-api:登录认证 + 全量评论是协议复杂、易变、坑多的原子(-352 风控、wbi 签名、cookie 刷新 correspond RSA、分页边界、楼中楼结构),工业级库已解决,手写会反复踩坑(参见 bilibili-api issue #979:QR 登录 cookie 缺 buvid3)。这是 github-gem-seeker"先复用,后创造"理念的应用。
| 模块 | 职责 |
|---|---|
auth.py |
扫码登录 + Credential 持久化(集成 bilibili-api QrCodeLogin) |
fetch.py |
采集:视频元数据/字幕(免认证 stdlib HTTP)+ 全量评论(bilibili-api async) |
distill.py |
蒸馏:全量评论去重去空(不按赞预筛)、时间轴格式化 |
render.py |
渲染 OKF Bundle:videos/transcripts/comments(复用官方 okf_lib.py);content/insights 由会话提炼后写入 |
okf_lib.py |
官方 OKF 序列化库(直接复用) |
search.py |
视频搜索:bilibili-api.search 免登录召回候选,空 bvid 过滤,错误分类(param_error/fetch_error) |
asr.py |
ASR 补字幕:yt-dlp 取音频 + FunASR 转写(可选依赖,--no-asr 可禁用) |
topics.py |
通用 BERTopic 模块(embedding+UMAP+HDBSCAN+c-TF-IDF),tools/cluster_comments.py 调用(可选依赖,仅评论 >1000 时用) |
browser_cookie.py / browser_act_fetch.py |
评论 412 反风控:DrissionPage(主)/ browser-act CLI(fallback)解挑战拿完整 cookie 集(可选依赖) |
cookie_cache.py |
主/fallback 共享的 412 token 缓存层(~/.bili2okf/,3h 新鲜度)+ session.json 登录态注入映射 |
- patelisii/OKF-Claude-Code —— OKF v0.1 规范与官方
okf_lib.py(复用OKFDocument+regenerate_indexes) - Nemo2011/bilibili-api —— B站 Python SDK(登录认证 + 全量评论采集集成其
QrCodeLogin/comment模块) - SocialSisterYi/bilibili-API-collect —— B站 API 协议文档