#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ 测试 B站 WBI API 字幕提取 """ import asyncio import json from playwright.async_api import async_playwright async def test_wbi_subtitle(bvid): """测试 WBI API 字幕""" url = f"https://www.bilibili.com/video/{bvid}" async with async_playwright() as playwright: browser = await playwright.chromium.launch(headless=True) context = await browser.new_context() page = await context.new_page() print(f"正在测试视频: {url}") print("=" * 80) # 首先获取 aid 和 cid print("\n1. 获取视频基本信息...") try: api_url = "https://api.bilibili.com/x/web-interface/view" response = await page.request.get(api_url, params={'bvid': bvid}) data = await response.json() if data.get('code') == 0: video_data = data.get('data', {}) print(f" 标题: {video_data.get('title')}") aid = video_data.get('aid') cid = video_data.get('cid') print(f" aid: {aid}") print(f" cid: {cid}") else: print(f" ❌ 失败: {data.get('message')}") await browser.close() return except Exception as e: print(f" ❌ 异常: {e}") await browser.close() return # 使用 WBI API 获取播放器信息(包含字幕) print("\n2. 使用 WBI API 获取播放器信息...") try: wbi_url = "https://api.bilibili.com/x/player/wbi/v2" wbi_response = await page.request.get(wbi_url, params={'aid': aid, 'cid': cid}) print(f" 状态码: {wbi_response.status}") if wbi_response.ok: wbi_data = await wbi_response.json() print(f" 响应码: {wbi_data.get('code')}") if wbi_data.get('code') == 0: player_data = wbi_data.get('data', {}) print(f"\n 数据结构:") print(f" {json.dumps(list(player_data.keys()), indent=4, ensure_ascii=False)}") # 检查字幕 subtitle_info = player_data.get('subtitle', {}) print(f"\n 字幕信息:") print(f" {json.dumps(subtitle_info, indent=4, ensure_ascii=False)}") subtitles_list = subtitle_info.get('subtitles', []) if subtitles_list: print(f"\n ✅ 找到 {len(subtitles_list)} 个字幕!") for i, sub in enumerate(subtitles_list): print(f" [{i+1}] {sub.get('lan_doc')} (lan={sub.get('id')}, type={sub.get('id_type')})") print(f" URL: {sub.get('subtitle_url')}") # 获取字幕内容 subtitle_url = sub.get('subtitle_url', '') if subtitle_url: full_url = f"https:{subtitle_url}" print(f"\n 正在获取字幕内容...") sub_response = await page.request.get(full_url) if sub_response.ok: sub_data = await sub_response.json() body = sub_data.get('body', []) print(f" ✅ 获取成功,共 {len(body)} 条字幕") print(f" 前3条字幕:") for j, item in enumerate(body[:3]): from_time = item.get('from', 0) to_time = item.get('to', 0) content = item.get('content', '') print(f" [{j+1}] [{from_time:.1f}s - {to_time:.1f}s] {content}") else: print(f" ❌ 获取失败: {sub_response.status}") else: print(f"\n ❌ 没有找到字幕") print(f" allow_submit: {subtitle_info.get('allow_submit')}") else: print(f" ❌ API 错误: {wbi_data.get('message')}") else: print(f" ❌ HTTP 错误: {wbi_response.status}") except Exception as e: print(f" ❌ 异常: {e}") import traceback traceback.print_exc() # 尝试不使用 wbi,使用旧版本 API print("\n3. 尝试旧版 API (v2)...") try: old_url = "https://api.bilibili.com/x/player/v2" old_response = await page.request.get(old_url, params={'bvid': bvid, 'cid': cid}) print(f" 状态码: {old_response.status}") if old_response.ok: old_data = await old_response.json() subtitle_info = old_data.get('data', {}).get('subtitle', {}) subtitles_list = subtitle_info.get('subtitles', []) print(f" 字幕数量: {len(subtitles_list)}") if subtitles_list: print(f" ✅ 旧版 API 找到字幕!") for sub in subtitles_list: print(f" {sub.get('lan_doc')}") except Exception as e: print(f" ❌ 异常: {e}") await browser.close() if __name__ == '__main__': bvid = "BV1KtFzzqEUG" asyncio.run(test_wbi_subtitle(bvid))