Python Playwright未渲染JS脚本致HTML加载不全,求解决方法
问题:Playwright无法渲染JS脚本,页面未完全加载
使用Python Playwright包加载https://www.bvl.com.pe/mercado/movimientos-diarios抓取数据时,页面始终无法完全加载。打印页面内容仅能看到script标签,几乎无其他有效内容,截图也为空白。尝试了网上找到的PageDown按键+等待的方法,依然无效,求正确加载页面的方案。
调试代码如下:
from playwright.async_api import async_playwright, Browser, Playwright, Page import asyncio async def main(): async with async_playwright() as P: browser = await P.chromium.launch(channel='chrome') page = await browser.new_page() await page.goto('https://www.bvl.com.pe/mercado/movimientos-diarios') # Literally the only possible fix i found online await page.keyboard.press('PageDown') await asyncio.sleep(5) print(await page.content()) await page.screenshot(path="screenshot.png", full_page=True) if __name__ == '__main__': asyncio.run(main_main())
解决方案
1. 修正代码低级错误
你的代码最后调用了asyncio.run(main_main()),但定义的入口函数是main(),这会直接导致报错,先修正为asyncio.run(main())。
2. 替换固定等待为Playwright原生等待机制
固定的asyncio.sleep(5)不可靠,应该用Playwright提供的精准等待方法,确保页面加载完成:
- 使用
wait_for_load_state等待页面进入networkidle状态(代表网络请求基本终止) - 或者直接等待页面上的关键元素出现,比如页面核心数据表格
3. 配置浏览器与页面参数
部分网站会针对无头模式、小视口做渲染限制,可调整以下配置:
- 启动有头浏览器(
headless=False),方便直观调试页面加载情况 - 设置匹配真实浏览器的视口尺寸
- 禁用缓存,避免旧缓存干扰页面加载
4. 模拟真实浏览器环境,规避反爬
部分网站会检测自动化工具,可添加以下配置模拟真实用户:
- 设置真实浏览器的User-Agent
- 显式启用JavaScript(默认启用,可强化配置)
修正后的完整代码
from playwright.async_api import async_playwright import asyncio async def main(): async with async_playwright() as p: # 启动有头Chrome方便调试,生产环境可改回headless=True browser = await p.chromium.launch(channel='chrome', headless=False) page = await browser.new_page( viewport={'width': 1920, 'height': 1080}, user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36' ) # 禁用缓存 await page.route("**/*", lambda route: route.continue_(headers={"Cache-Control": "no-cache"})) # 等待网络请求完全稳定后再继续 await page.goto( 'https://www.bvl.com.pe/mercado/movimientos-diarios', wait_until='networkidle' ) # 等待页面核心表格加载(可根据实际页面结构调整选择器) await page.wait_for_selector('.table', timeout=10000) # 滚动到底部触发懒加载内容(如果有) await page.evaluate('window.scrollTo(0, document.body.scrollHeight)') await page.wait_for_timeout(2000) # 短等待确保懒加载内容渲染 print(await page.content()) await page.screenshot(path="screenshot.png", full_page=True) await browser.close() if __name__ == '__main__': asyncio.run(main())
额外调试建议
- 用有头模式运行时,观察页面是否有弹窗、验证码或需要手动交互的环节
- 启用追踪功能录制页面加载过程:
await page.context.tracing.start(screenshots=True, snapshots=True),事后导出追踪文件分析加载失败原因 - 打印控制台JS错误排查问题:
page.on('console', lambda msg: print(msg.text))
内容的提问来源于stack exchange,提问作者user12358312
相关产品推荐
相关产品推荐

