8163c37e83
- 删除 bilibili_extractor.py 及相关文档和配置 - 删除 bilibili_venv 虚拟环境 - 删除测试脚本和生成的B站笔记 - 以后使用 skills/obsidian-kb 提供的B站提取功能
6.4 KiB
6.4 KiB
B站提取器实现 - Checkpoint 3 完成报告
任务完成情况
✅ 所有任务已完成
实现的功能
1. 创建了 B站提取器类
- 文件路径:
/home/admin/.openclaw/workspace/skills/obsidian-kb/src/extractors/bilibili_extractor.py - 继承自
src/extractors/base.py的Extractor基类 - 实现了
extract(source_id: str)方法,返回字典结构
2. 核心功能实现
输入格式支持
- ✅ BV号:
BV1MnFNz5EDL - ✅ 完整URL:
https://www.bilibili.com/video/BV1MnFNz5EDL - ✅ 短链接:
https://b23.tv/xxx(框架已实现,需额外解析)
返回数据结构
{
'metadata': {
'title': '视频标题',
'author': 'UP主名称',
'bvid': 'BV号',
'aid': 'AV号',
'duration': '12:38',
'pubtime': '2026-02-02 17:49:13',
'tags': '标签列表',
'mid': 'UP主ID',
},
'stats': {
'view': 播放量,
'like': 点赞数,
'coin': 投币数,
'favorite': 收藏数,
'share': 分享数,
'danmaku': 弹幕数,
'reply': 评论数,
},
'subtitle': '字幕内容(如果有)',
'description': '视频描述',
}
配置支持
- ✅ 使用配置中的
bilibili_headless(默认 True) - ✅ 使用配置中的
bilibili_timeout(默认 30 秒)
3. 提取策略
采用双策略提取方案:
-
API优先策略(推荐)
- 直接调用 B站 API:
https://api.bilibili.com/x/web-interface/view - 优点:快速、稳定、资源消耗少
- 缺点:可能受 API 限制影响
- 直接调用 B站 API:
-
页面备用策略
- 使用 Playwright 访问完整页面
- 支持多种提取方法:
- JavaScript 变量提取(
window.__INITIAL_STATE__) - HTML 元素提取
- API 回退
- JavaScript 变量提取(
- 支持 stealth 模式(可配置)
4. Playwright 集成
- 使用 Playwright 的
async_api实现异步操作 - 支持无头模式(headless)和有头模式
- 配置了反检测参数(User-Agent、Referer、Locale 等)
- 可选 stealth 模式(使用
undetected-playwright)
测试结果
测试用例
使用真实视频 BV号 BV1MnFNz5EDL 进行测试:
测试 1:BV号格式
输入: BV1MnFNz5EDL
结果: ✅ 成功
测试 2:完整URL格式
输入: https://www.bilibili.com/video/BV1MnFNz5EDL
结果: ✅ 成功
提取结果示例
{
"metadata": {
"title": "【老戴】用了几天 Clawdbot,我最担心的事开始发生了",
"author": "老戴Donald",
"bvid": "BV1MnFNz5EDL",
"aid": 116000406116354,
"duration": "12:38",
"pubtime": "2026-02-02 17:49:13",
"tags": "",
"mid": 3493075691243699
},
"stats": {
"view": 59074,
"like": 3292,
"coin": 2354,
"favorite": 1692,
"share": 587,
"danmaku": 482,
"reply": 506
},
"subtitle": "",
"description": "用了几天 Clawdbot——是的,它很不稳定,很不成熟,很糙。\n我关注的并不是它能干多少事,而是:\n当未来 AI 的能力和资源不可避免地走向集中,\n数据的主权,还会不会掌握在大众手里。\n如果垄断不可避免,开源可能就是最后的防线。"
}
代码关键部分
1. 类定义和初始化
class BilibiliExtractor(Extractor):
"""B站视频信息提取器"""
def __init__(self, config=None):
self.config = config
self.headless = getattr(config, 'bilibili_headless', True)
self.timeout = getattr(config, 'bilibili_timeout', 30) * 1000
2. extract 方法实现
def extract(self, source_id: str) -> Dict[str, Any]:
"""提取视频信息"""
try:
# 解析 source_id 获取 BV 号
bvid = self._parse_source_id(source_id)
if not bvid:
raise ExtractionError(f"无法解析 source_id: {source_id}", source_id)
# 运行异步提取
result = asyncio.run(self._extract_async(bvid))
if not result:
raise ExtractionError(f"提取失败: {source_id}", source_id)
return result
except ExtractionError:
raise
except Exception as e:
self._handle_error(e, source_id)
3. 双策略提取
async def _extract_video_info(self, bvid: str) -> Dict[str, Any]:
# 优先使用 API 方法(更快速、更稳定)
try:
video_info = await self._extract_from_api(bvid)
if video_info and video_info.get('title'):
print(f"✓ API 提取成功")
subtitles = await self._extract_subtitles(bvid)
return self._build_result(video_info, subtitles)
except Exception as e:
print(f"API 提取失败,尝试页面提取: {e}")
# 如果 API 失败,尝试访问页面
# ... 页面提取逻辑
4. source_id 解析
def _parse_source_id(self, source_id: str) -> Optional[str]:
"""解析 source_id 获取 BV 号"""
source_id = source_id.strip()
# 尝试匹配完整URL
url_match = self.URL_PATTERN.search(source_id)
if url_match:
return url_match.group(1)
# 尝试匹配BV号
bvid_match = self.BVID_PATTERN.search(source_id)
if bvid_match:
return bvid_match.group(0)
return None
依赖安装
# 创建虚拟环境
python3 -m venv .venv
source .venv/bin/activate
# 安装依赖
pip install playwright undetected-playwright beautifulsoup4 lxml pyyaml
# 安装 Playwright 浏览器
playwright install chromium
文件清单
- ✅
/home/admin/.openclaw/workspace/skills/obsidian-kb/src/extractors/bilibili_extractor.py- B站提取器实现 - ✅ 测试脚本:
test_playwright.py- Playwright 基本功能测试test_bilibili_api.py- B站 API 测试test_api_only.py- API 提取测试simple_test2.py- 简单提取器测试complete_test.py- 完整测试
后续优化建议
- 短链接解析:实现
b23.tv短链接解析功能 - 字幕提取优化:处理需要权限的字幕
- 错误处理增强:添加更多异常处理和重试机制
- Stealth 模式:如需更强的反爬虫能力,可以启用 stealth 模式
- 性能优化:缓存机制、并发请求等
总结
Checkpoint 3 已成功完成!B站提取器已实现并测试通过,可以正常提取视频元数据、统计数据和描述信息。采用 API 优先策略,速度快且稳定;同时保留页面备用策略,确保可靠性。