Selenium Python3:Chrome标签加载图标超时检测失效问题求助
问题分析与解决方案
为什么set_page_load_timeout没触发超时?
set_page_load_timeout并不完全过时,但它的触发逻辑只监听浏览器的**window.load事件**——也就是页面初始HTML、图片、样式、脚本等静态资源全部加载完成的事件。
现在多数现代页面是动态加载或单页应用:初始静态资源加载完成后,window.load事件就会触发,但页面还会通过AJAX/fetch异步加载后续内容,此时标签页的加载图标仍会转动,但set_page_load_timeout已经停止监控了。你的代码里页面初始加载在2秒内完成,后续动态加载不会触发这个超时,所以没报错。
这个方法仅适用于传统整页刷新的场景,完全不匹配动态加载页面的需求。
自定义加载超时检测方案
要检测Chrome标签页加载图标是否停止转动,我们可以借助Chrome DevTools协议(CDP)监控页面加载状态与网络请求,结合自定义超时逻辑实现需求。
方案1:严格监控加载状态+网络请求
通过CDP获取页面加载状态,同时检查是否有未完成的网络请求,两者都完成则判定加载结束,超时则抛出错误。
from selenium import webdriver from webdriver_manager.chrome import ChromeDriverManager from selenium.webdriver.chrome.service import Service from selenium.common.exceptions import TimeoutException import time options = webdriver.ChromeOptions() options.add_argument("--start-maximized") driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=options) # 启用CDP的Network和Page模块 driver.execute_cdp_cmd("Network.enable", {}) driver.execute_cdp_cmd("Page.enable", {}) def wait_for_page_load(timeout=10): start_time = time.time() while time.time() - start_time < timeout: # 获取页面导航状态 nav_status = driver.execute_cdp_cmd("Page.getNavigationStatus", {})["status"] # 获取未完成的网络请求数量 pending_reqs = driver.execute_cdp_cmd("Network.getPendingRequests", {})["pendingRequests"] # 导航状态为complete且无未完成请求,判定加载完成 if nav_status == "complete" and len(pending_reqs) == 0: return True time.sleep(0.5) # 超时抛出异常 raise TimeoutException(f"页面加载超时:超过{timeout}秒仍未停止加载") try: driver.get('https://apps.varejonline.com.br/relatorios/relatorios/base/analisevendasperiodo/0') wait_for_page_load(timeout=2) # 设置2秒超时测试 print("页面加载完成") except TimeoutException as e: print(e) finally: driver.quit()
方案2:简化版——监控文档就绪状态+页面加载状态
如果不需要严格监控所有网络请求,可结合document.readyState与CDP页面加载状态判断:
from selenium import webdriver from webdriver_manager.chrome import ChromeDriverManager from selenium.webdriver.chrome.service import Service from selenium.common.exceptions import TimeoutException import time options = webdriver.ChromeOptions() options.add_argument("--start-maximized") driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=options) driver.execute_cdp_cmd("Page.enable", {}) def wait_for_page_load(timeout=10): start_time = time.time() while time.time() - start_time < timeout: # 检查文档就绪状态 ready_state = driver.execute_script("return document.readyState") # 检查页面加载状态 nav_status = driver.execute_cdp_cmd("Page.getNavigationStatus", {})["status"] if ready_state == "complete" and nav_status == "complete": return True time.sleep(0.5) raise TimeoutException(f"页面加载超时:超过{timeout}秒仍未停止加载") try: driver.get('https://apps.varejonline.com.br/relatorios/relatorios/base/analisevendasperiodo/0') wait_for_page_load(timeout=2) print("页面加载完成") except TimeoutException as e: print(e) finally: driver.quit()
注意事项
- 必须启用CDP对应模块(如
Page.enable、Network.enable),否则无法获取状态数据。 - 可根据页面实际情况调整等待间隔(
time.sleep(0.5)):间隔太小会增加资源消耗,太大可能导致超时判断延迟。 - 若页面存在持续后台请求(如心跳接口),需在代码中过滤特定URL,避免误判超时。
内容的提问来源于stack exchange,提问作者Davi Americo
相关产品推荐
相关产品推荐

