Selenium+ChromeDriver爬取PDF遇TimeoutException,如何延长超时时间?
解决Selenium ChromeDriver爬取PDF时的TimeoutException问题
遇到爬取到6000条左右记录时持续超时的问题,我来给你几个实用的解决方案——先从你问的延长超时限制说起,再补充一些针对大规模爬取的优化建议:
一、延长Selenium超时限制的几种方法
1. 全局隐式等待设置
如果你希望所有元素查找操作都默认等待更长时间,可以设置全局隐式等待,覆盖默认的超时逻辑:
# 设置全局隐式等待为300秒(5分钟),可根据实际情况调整时长 driver.implicitly_wait(300)
注意:隐式等待是全局生效的,一旦设置后,所有find_element类的方法都会等待指定时间直到元素出现。但不要和显式等待混用,可能会导致等待时间叠加。
2. 针对特定操作的显式等待
更推荐用显式等待,只针对关键操作(比如等待PDF加载完成)设置更长超时,这样不会拖慢其他快速操作的效率:
from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By # 实例化等待对象,设置超时为300秒 wait = WebDriverWait(driver, 300) # 等待PDF对应的元素出现(比如embed/iframe标签,根据目标站点的实际结构调整) pdf_element = wait.until(EC.presence_of_element_located((By.TAG_NAME, "embed")))
这种方式灵活性更高,你可以针对不同页面的关键元素设置不同的超时时间。
3. 设置页面加载超时
如果超时是因为页面整体加载太慢导致的,可以直接设置页面加载的超时阈值:
# 设置页面加载超时为300秒 driver.set_page_load_timeout(300)
如果有些页面一直处于加载状态(比如有持续请求的广告或统计脚本),还可以在等待一段时间后强制停止加载:
driver.get(site_url) # 等待10秒后强制停止加载(如果页面还没加载完成) time.sleep(10) driver.execute_script("window.stop();")
二、针对大规模爬取的优化建议
除了延长超时,你爬取6000条记录的场景下,还有几个点可以优化,从根源减少超时概率:
- 调整浏览器清理频率:每200次刷新其实是合理的,但可以在每次刷新或爬取N条后,清理浏览器的缓存和Cookie,避免浏览器因缓存堆积变慢:
# 删除所有Cookie driver.delete_all_cookies() # 清除localStorage driver.execute_script("window.localStorage.clear();") # 清除sessionStorage driver.execute_script("window.sessionStorage.clear();")
- 优化Chrome启动参数:禁用不必要的资源加载,减少浏览器的资源占用,比如禁用图片、启用无头模式:
from selenium.webdriver.chrome.options import Options chrome_options = Options() # 无头模式(后台运行,节省系统资源) chrome_options.add_argument('--headless=new') # 禁用图片加载,大幅提升页面加载速度 chrome_options.add_argument('--disable-images') # 禁用不必要的插件 chrome_options.add_argument('--disable-plugins') # 禁用缓存 chrome_options.add_argument('--disable-cache') driver = webdriver.Chrome(options=chrome_options)
- 增加重试机制:遇到超时不要直接放弃,重试2-3次——很多时候超时是临时的网络波动或服务器负载过高导致的:
from selenium.common.exceptions import TimeoutException max_retries = 3 for idx, site in enumerate(site_list): retries = 0 success = False while retries < max_retries: try: driver.get(site) # 等待PDF加载的逻辑 wait = WebDriverWait(driver, 300) wait.until(EC.presence_of_element_located((By.TAG_NAME, "embed"))) # 执行PDF下载/提取操作 success = True break except TimeoutException: retries += 1 print(f"处理第{idx+1}个站点超时,重试第{retries}次") driver.refresh() if not success: print(f"第{idx+1}个站点多次重试失败,已记录到失败列表") # 可将失败站点存入文件,后续单独处理
- 拆分任务并行处理:如果机器性能允许,可以用多线程或多进程拆分站点列表,同时运行多个Chrome实例(每个线程对应一个driver),但注意不要同时发起太多请求,避免触发目标网站的反爬机制。
内容的提问来源于stack exchange,提问作者Neue1987
相关产品推荐
相关产品推荐

