如何在Selenium/Python(Chrome/Edge)中检测页面加载失败或加载异常?
如何在Selenium/Python(Chrome/Edge)中检测页面加载失败或加载异常?
嘿,我太懂你选课抢时段的痛苦了——大学选课系统高峰期的卡顿、假加载简直是抢课党的噩梦!针对你遇到的页面直接报错、看似在加载实则假死最后失败的问题,这里有几个实用的思路,帮你的Selenium bot及时止损,不用傻等超时:
1. 用Chrome DevTools协议(CDP)捕获页面HTTP错误状态码
Selenium本身没法直接获取HTTP响应状态码,但Chrome/Edge都支持CDP,我们可以用它监听网络请求,快速捕获服务器返回的明确错误(比如503服务繁忙、504网关超时),不用等到页面超时。
示例代码:
from selenium import webdriver from selenium.webdriver.common.by import By def check_page_load_status(driver): # 启用网络监听 driver.execute_cdp_cmd("Network.enable", {}) responses = [] # 监听页面主请求的响应状态 def handle_response(response): if response["response"]["url"] == driver.current_url: responses.append(response["response"]["status"]) driver.execute_cdp_cmd("Network.responseReceived", {}, handle_response) # 短时间等待网络请求完成 driver.implicitly_wait(10) # 检查是否有错误状态码 for status in responses: if 400 <= status < 600: return False, f"页面加载失败,状态码:{status}" return True, "页面加载正常" # 初始化浏览器 driver = webdriver.Chrome() driver.get("你的选课系统URL") success, msg = check_page_load_status(driver) if not success: print(msg) driver.refresh() # 触发刷新
2. 监控页面“活跃度”,识别假加载
假加载的核心是:浏览器看起来在加载,但网络请求停滞、DOM没有更新。我们可以从两个维度监控:
- 监控网络请求是否停滞:设定一个时长(比如30秒),如果超过这个时间没有新的网络请求完成,判定为假加载;
- 检查DOM是否停止变化:定期抓取页面关键区域的HTML哈希值,如果连续几次检查哈希值都不变,说明页面没在加载。
示例代码(检查DOM活跃度):
import hashlib import time from selenium.webdriver.common.by import By def is_page_stalled(driver, check_interval=5, max_checks=3): # 选取页面关键元素(比如选课系统的主容器,根据实际页面调整) key_element = driver.find_element(By.ID, "course-registration-container") previous_hash = None stall_count = 0 for _ in range(max_checks): current_html = key_element.get_attribute("innerHTML") current_hash = hashlib.md5(current_html.encode()).hexdigest() if current_hash == previous_hash: stall_count += 1 if stall_count >= max_checks: return True # 页面假死 else: stall_count = 0 previous_hash = current_hash time.sleep(check_interval) return False # 使用示例 if is_page_stalled(driver): print("页面假加载,开始刷新") driver.refresh()
3. 结合显式等待+错误提示检测
不要只用固定时长的显式等待,我们可以在等待过程中定期检查页面是否出现了“服务器繁忙”“加载失败”这类错误提示文本,如果出现就立刻刷新;同时给等待设置一个合理的最大超时(比如90秒),超时也触发刷新。
示例代码:
from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By def wait_for_page_ready(driver, timeout=90): try: # 等待关键元素出现(比如选课按钮,根据实际页面调整) WebDriverWait(driver, timeout, poll_frequency=2).until( EC.presence_of_element_located((By.ID, "select-course-btn")) ) return True except: # 检查是否有常见错误提示 error_texts = ["服务器繁忙", "加载失败", "无法连接", "请求超时"] for text in error_texts: if text in driver.page_source: print(f"检测到错误提示:{text}") return False # 超时也判定为加载异常 print("页面加载超时") return False # 使用示例 if not wait_for_page_ready(driver): driver.refresh()
4. 用JavaScript增强页面状态判断
除了document.readyState == 'complete',我们还可以通过JS判断页面是否真的就绪,或者是否存在隐藏的错误状态:
示例代码:
def is_page_loaded_successfully(driver): ready_state = driver.execute_script("return document.readyState") if ready_state != "complete": return False # 检查页面是否有隐藏的错误容器(根据实际页面调整选择器) has_error = driver.execute_script("return document.querySelector('.error-container') !== null") if has_error: return False return True if not is_page_loaded_successfully(driver): driver.refresh()
总结
建议把这些方法组合起来用:先用CDP抓明确的HTTP错误,再用DOM/网络监控抓假加载,最后用带错误检测的显式等待兜底。毕竟选课系统高峰期啥奇葩情况都有,多做几层判断能让你的bot更灵活,少浪费时间在无效等待上。
备注:内容来源于stack exchange,提问作者Gokalp
相关产品推荐
相关产品推荐

