Selenium使用webdriver.get访问多URL时出现TimedPromise超时错误
诊断排查与解决思路
1. 调整页面加载策略
Selenium默认使用normal加载策略,会等待页面所有资源(广告、第三方统计脚本、iframe等)完全加载后才返回driver.get()的执行结果,长时间运行后很容易因为个别资源加载失败、网站反爬限速触发超时。
可以将加载策略调整为eager,仅等待DOM树加载完成就返回,无需等待静态资源加载:
options.page_load_strategy = 'eager'
如果你的爬取逻辑不需要等待页面自动加载完成,也可以设置为none,后续自行通过显式等待判断页面状态。
2. 显式配置合理的超时阈值
默认的300秒超时时间过长,建议拆分配置三类超时规则:
# 初始化driver后立即配置 self.requestor.set_page_load_timeout(30) # 页面加载最大等待30秒 self.requestor.set_script_timeout(30) # JS脚本执行最大等待30秒 self.requestor.implicitly_wait(10) # 元素查找默认隐式等待10秒
3. 增加超时异常的重试逻辑
不需要一触发超时就直接销毁driver,可先捕获TimeoutException后执行停止页面加载、刷新操作,大部分场景下可恢复正常使用:
from selenium.common.exceptions import TimeoutException def get_url(self, url): try: self.requestor.get(url) except TimeoutException: # 停止当前页面加载,避免卡住 self.requestor.execute_script("window.stop()") # 可选:重试一次加载 # self.requestor.get(url) time.sleep(3)
4. 排查资源泄漏问题
Firefox长时间运行后会堆积缓存、Cookie、内存占用,逐渐变慢甚至卡住:
- 每爬取一定数量的URL后主动清理Cookie:
self.requestor.delete_all_cookies() - 无需可视化操作的话开启无头模式,大幅降低资源占用:
options.headless = True - 可通过启动参数禁用图片、不必要的插件减少加载压力:
options.add_argument('--disable-images') options.add_argument('--disable-plugins')
5. 验证版本兼容性
你当前使用的Selenium 3.141.0 + Firefox 90 + geckodriver 0.29.1组合存在已知的长时间运行连接泄漏bug,可选两种优化方案:
- 升级到Selenium 4.x + 最新版Firefox + 对应版本geckodriver,修复了大量稳定性问题
- 降级到更稳定的兼容组合:Firefox 78 ESR + geckodriver 0.27.0,长期运行的稳定性更高
6. 优化driver复用逻辑
最简便的规避方案是设置driver的生命周期:每爬取20~50个URL(可根据实际运行情况调整)就主动调用self.requestor.quit()销毁旧实例,重新初始化新的driver,从根本上避免长时间运行导致的各类累积问题。
另外补充代码优化点:driver.get()方法没有返回值,你代码中将其赋值给self.response是无效操作,可直接删除。固定的time.sleep(3)可以替换为显式等待目标页面元素出现的逻辑,效率更高。
内容的提问来源于stack exchange,提问作者sir_chocolate_soup

