Selenium WebDriver+Timeloop无法捕获TimeoutException?求原因与解决方法
问题原因分析
异常捕获顺序错误
TimeoutException是WebDriverException的子类,你的代码先捕获父类WebDriverException,导致TimeoutException会被这个块优先拦截。更关键的是,你在该块里访问了e.Message——Python中异常的消息属性是小写的e.message,而Selenium的异常更建议直接用str(e)获取完整信息。访问不存在的e.Message会抛出AttributeError,这个未被捕获的异常直接导致Timeloop的线程崩溃,进而整个定时任务停止。代码存在未初始化/未定义的变量
- 没有初始化Timeloop实例
tl = Timeloop(),启动时会直接抛出NameError PROXY变量未定义,运行时也会触发NameError
修复方案
针对上述问题,调整代码如下:
- 调整异常捕获顺序,先捕获子类TimeoutException,再捕获父类WebDriverException
- 修正异常信息的获取方式,用
str(e)替代错误的e.Message - 初始化Timeloop实例
- 定义PROXY变量(如果不需要代理,直接删除
--proxy-server这一行) - 使用finally块确保WebDriver无论是否异常都能被关闭,避免资源泄漏
- 可选:设置页面加载超时,让超时触发更及时
修复后的完整代码
from selenium import webdriver from selenium.webdriver.chrome.options import Options from selenium.common.exceptions import TimeoutException, WebDriverException from timeloop import Timeloop from datetime import timedelta url = "https://example.com" PROXY = "your-proxy-address:port" # 替换为实际代理,不需要则删除该行 tl = Timeloop() # 初始化Timeloop实例 @tl.job(interval=timedelta(seconds=120)) def scrap_content(): web_driver = None try: options = Options() options.add_argument('--headless') options.add_argument('--disable-gpu') options.add_argument('--disable-extensions') if 'PROXY' in locals(): # 仅当PROXY定义时添加代理参数 options.add_argument(f'--proxy-server={PROXY}') web_driver = webdriver.Chrome(options=options) web_driver.set_page_load_timeout(30) # 设置30秒页面加载超时 web_driver.get(url) # 这里可以添加获取网页源码的逻辑,比如: # page_source = web_driver.page_source # print(page_source) except TimeoutException as e: print(f"Timeout Exception: {str(e)}") except WebDriverException as e: print(f"Web Driver Exception: {str(e)}") finally: if web_driver is not None: web_driver.quit() # 确保driver被关闭 if __name__ == "__main__": tl.start(block=True)
额外说明
- 使用finally块能保证无论是否发生异常,WebDriver实例都会被正确关闭,避免浏览器进程残留
- 设置
set_page_load_timeout可以控制页面加载的最大等待时间,避免无限制等待 - 异常捕获顺序必须遵循先子类后父类的原则,否则子类异常会被父类拦截,无法针对性处理
内容的提问来源于stack exchange,提问作者Raptor
相关产品推荐
相关产品推荐

