#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ 测试动态字幕加载 - 播放视频并监听字幕请求 """ import asyncio import json from playwright.async_api import async_playwright async def test_dynamic_subtitle(bvid): """测试动态字幕加载""" 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) # 监听所有网络请求,查找字幕相关的请求 subtitle_requests = [] def handle_request(request): url = request.url # 记录可能包含字幕的请求 if 'subtitle' in url.lower() or 'cc' in url.lower(): subtitle_requests.append({ 'url': url, 'method': request.method, 'resource_type': request.resource_type }) print(f"📡 发现字幕请求: {url[:100]}...") page.on('request', handle_request) print("\n1. 访问页面并等待加载...") await page.goto(url, wait_until='networkidle', timeout=60000) await asyncio.sleep(3) # 模拟播放视频(点击播放按钮) print("\n2. 尝试播放视频...") try: # 尝试点击播放按钮 play_button = await page.query_selector('.bpx-player-ctrl-play') if play_button: await play_button.click() await asyncio.sleep(5) # 等待视频播放 print(" ✅ 已点击播放按钮") else: print(" ⚠️ 未找到播放按钮") await asyncio.sleep(5) # 无论如何等待一下 except Exception as e: print(f" ⚠️ 播放异常: {e}") await asyncio.sleep(5) # 检查是否有字幕按钮 print("\n3. 检查字幕按钮...") try: subtitle_button = await page.query_selector('.bpx-player-ctrl-subtitle') if subtitle_button: print(" ✅ 找到字幕按钮") is_enabled = await subtitle_button.is_enabled() print(f" 字幕按钮状态: {'可用' if is_enabled else '不可用'}") # 尝试点击字幕按钮 if is_enabled: await subtitle_button.click() await asyncio.sleep(2) print(" ✅ 已点击字幕按钮") else: print(" ❌ 未找到字幕按钮") except Exception as e: print(f" ⚠️ 检查字幕按钮异常: {e}") # 等待更多网络请求 print("\n4. 等待字幕请求...") await asyncio.sleep(3) # 显示捕获的字幕请求 print(f"\n5. 捕获的字幕请求 (共 {len(subtitle_requests)} 个):") if subtitle_requests: for i, req in enumerate(subtitle_requests): print(f"\n [{i+1}] {req['method']} {req['resource_type']}") print(f" {req['url']}") else: print(" ❌ 未捕获到字幕请求") # 尝试从页面中提取字幕文本 print("\n6. 尝试从页面提取字幕文本...") try: # B站字幕通常在 .bpx-player-subtitle-item 元素中 subtitle_items = await page.query_selector_all('.bpx-player-subtitle-item') if subtitle_items: print(f" ✅ 找到 {len(subtitle_items)} 个字幕元素") # 获取前几个字幕 for i, item in enumerate(subtitle_items[:5]): text = await item.inner_text() print(f" [{i+1}] {text}") else: print(" ❌ 未找到字幕元素") except Exception as e: print(f" ⚠️ 提取字幕文本异常: {e}") # 尝试获取所有文本内容(包含动态加载的字幕) print("\n7. 检查页面中是否有字幕相关的数据...") try: # 尝试从 window 对象中获取字幕数据 script_result = await page.evaluate(''' () => { const results = {}; // 检查不同的位置 if (window.__playinfo__?.data?.subtitle) { results.playinfo_subtitle = window.__playinfo__.data.subtitle; } if (window.__subtitle__ || window.__subtitles__) { results.subtitle_var = window.__subtitle__ || window.__subtitles__; } // 检查播放器实例 const player = document.querySelector('.bpx-player-container')?.__player__; if (player?.subtitlePlugin) { results.player_subtitle = Object.keys(player.subtitlePlugin); } return results; } ''') if script_result: print(f" 找到的字幕数据: {json.dumps(script_result, indent=8, ensure_ascii=False)}") else: print(" 未找到字幕相关的数据") except Exception as e: print(f" ⚠️ 检查页面数据异常: {e}") await browser.close() print("\n" + "=" * 80) print("测试完成") print("=" * 80) if __name__ == '__main__': bvid = "BV1KtFzzqEUG" asyncio.run(test_dynamic_subtitle(bvid))