This repository has been archived on 2026-02-15. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
openclaw-skills/CHECKPOINT_3_REPORT.md
T
OpenClaw Agent 8163c37e83 refactor: 移除bilibili_extractor插件,改用obsidian-kb
- 删除 bilibili_extractor.py 及相关文档和配置
- 删除 bilibili_venv 虚拟环境
- 删除测试脚本和生成的B站笔记
- 以后使用 skills/obsidian-kb 提供的B站提取功能
2026-02-07 14:44:58 +08:00

6.4 KiB
Raw Blame History

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. 提取策略

采用双策略提取方案:

  1. API优先策略(推荐)

    • 直接调用 B站 API:https://api.bilibili.com/x/web-interface/view
    • 优点:快速、稳定、资源消耗少
    • 缺点:可能受 API 限制影响
  2. 页面备用策略

    • 使用 Playwright 访问完整页面
    • 支持多种提取方法:
      • JavaScript 变量提取(window.__INITIAL_STATE__)
      • HTML 元素提取
      • API 回退
    • 支持 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

文件清单

  1. ✅ /home/admin/.openclaw/workspace/skills/obsidian-kb/src/extractors/bilibili_extractor.py - B站提取器实现
  2. ✅ 测试脚本:
    • test_playwright.py - Playwright 基本功能测试
    • test_bilibili_api.py - B站 API 测试
    • test_api_only.py - API 提取测试
    • simple_test2.py - 简单提取器测试
    • complete_test.py - 完整测试

后续优化建议

  1. 短链接解析:实现 b23.tv 短链接解析功能
  2. 字幕提取优化:处理需要权限的字幕
  3. 错误处理增强:添加更多异常处理和重试机制
  4. Stealth 模式:如需更强的反爬虫能力,可以启用 stealth 模式
  5. 性能优化:缓存机制、并发请求等

总结

Checkpoint 3 已成功完成!B站提取器已实现并测试通过,可以正常提取视频元数据、统计数据和描述信息。采用 API 优先策略,速度快且稳定;同时保留页面备用策略,确保可靠性。