Pyppeteer配置{'waitUntil':'networkidle0'}未等待页面完全加载问题
根因说明
networkidle0的触发逻辑为页面网络请求数持续500ms为0,仅保证静态资源加载完成,不覆盖客户端JS动态渲染场景。目标元素.get-the-list是静态资源加载完成后由JS动态生成,因此page.goto触发networkidle0时目标元素还未插入DOM,后续调用soup.select会执行失败。硬编码9秒等待刚好覆盖了JS渲染耗时,因此可以正常执行,但稳定性受网络、设备性能影响极大。
修复方案
将硬编码等待替换为等待目标元素渲染完成,同时给page.goto配置多等待条件提升稳定性,修改后的完整代码如下:
import requests from bs4 import BeautifulSoup import time import os import pyppeteer from pyppeteer import launch import asyncio import subprocess AGENT_DIR = os.path.dirname(__file__) + r'\data\agents' SAVE_FILE = os.path.join(AGENT_DIR, 'latest.txt') URL = 'https://techblog.willshouse.com/2012/01/03/most-common-user-agents/' def get_latest_agents(): ''' 从{URL}站点获取最常用的最新user agent 保存到文本文件{SAVE_FILE} ''' async def scrape(): url = URL browser = await launch(headless = False) page = await browser.newPage() # 同时等待load事件和networkidle0,避免提前返回 await page.goto(url, {'waitUntil': ['load', 'networkidle0'], 'timeout': 30000}) # 等待目标元素渲染完成,最长等10秒 await page.waitForSelector('.get-the-list', {'timeout': 10000}) content = await page.content() soup = BeautifulSoup(content, 'html.parser') agents = soup.select('.get-the-list')[0].text print(agents) await browser.close() loop = asyncio.get_event_loop() response = loop.run_until_complete(scrape()) if __name__ == '__main__': # 先杀掉所有chrome进程,避免pyppeteer关闭异常导致的残留 subprocess.call(['taskkill', '/F', '/im', 'chrome.exe']) get_latest_agents()
核心修改点
- 用
page.waitForSelector替代硬编码等待,仅当目标元素出现在DOM中才执行后续逻辑,兼顾执行效率和稳定性 page.goto的waitUntil参数传入数组,可同时满足多个等待条件,进一步降低提前返回的概率- 给所有异步等待逻辑添加显式超时配置,避免异常场景下脚本无限挂起
内容的提问来源于stack exchange,提问作者MasayoMusic
相关产品推荐
相关产品推荐

