Python Selenium爬取时按钮操作卡住触发TimeoutException如何解决
问题根因拆解
- 元素定位错误:你代码里选的按钮XPath
//button[@class='md-icon-button main-menu md-button md-ink-ripple']是网站的侧边主菜单按钮,不是切换日期的箭头按钮。点击后弹出的侧边栏带全屏半透明蒙版,会遮挡住页面上所有可交互元素,包括导出CSV的按钮,导致Selenium判断元素不可点击,触发超时。 - 等待时长设置过短:目标网站是境外服务,异步加载数据的延迟较高,你设置的2秒显式等待根本覆盖不到切页后表格、导出按钮完全渲染完成的时间点。
- 未配置Chrome自动下载规则:Chrome默认下载时会弹出保存路径确认弹窗,弹窗出现后会阻断所有页面交互,哪怕元素加载完成也无法点击。
- 缺少切页状态校验:点击箭头后没有等待页面完成数据刷新,就直接查找导出按钮,容易定位到上一页面的残留元素,或者因元素未渲染完成触发超时。
修正实现方案
首先配置Chrome的自动下载规则,跳过下载弹窗;其次修正元素定位逻辑,排除误选的主菜单按钮;最后拉长等待时长,增加切页状态校验,流程如下:
- 配置Chrome参数,禁用下载弹窗、指定本地下载路径
- 修正切页按钮的XPath,明确排除带
main-menu类名的主菜单按钮,定位到真正的前进箭头按钮 - 将显式等待时长从2秒调整为15秒,适配境外网站的网络延迟
- 每次切页后先校验URL的日期参数是否更新,再等待导出按钮可点击
- 每次下载完成后增加短暂等待,避免触发网站反爬限流
修正后可直接运行的代码
from selenium import webdriver from selenium.webdriver.chrome.service import Service from webdriver_manager.chrome import ChromeDriverManager from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC import time # 配置Chrome自动下载规则 chrome_options = webdriver.ChromeOptions() # 替换为你本地实际的CSV存储文件夹路径 download_path = "/your/local/csv/storage/folder" chrome_prefs = { "download.default_directory": download_path, "download.prompt_for_download": False, "download.directory_upgrade": True, "safebrowsing.enabled": True } chrome_options.add_experimental_option("prefs", chrome_prefs) # 关闭自动化控制提示条 chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"]) chrome_options.add_experimental_option('useAutomationExtension', False) driver = webdriver.Chrome( service=Service(ChromeDriverManager().install()), options=chrome_options ) driver.maximize_window() # 初始化15秒显式等待 wait = WebDriverWait(driver, 15) driver.get('https://demanda.ree.es/visiona/peninsula/demanda/tablas/2021-03-25/2') # 记录初始页面URL,用于校验切页是否完成 initial_url = driver.current_url # 等待首次页面加载完成 wait.until(EC.element_to_be_clickable((By.XPATH, "//span[@class='export-csv']"))) for i in range(1000): # 定位正确的下一天切页按钮:排除主菜单按钮,匹配带前进箭头的按钮 next_day_button = wait.until( EC.element_to_be_clickable( (By.XPATH, "//button[contains(@class, 'md-icon-button') and not(contains(@class, 'main-menu')) and .//md-icon[text()='arrow_forward']]") ) ) next_day_button.click() # 等待页面日期参数更新,确认切页完成 wait.until(lambda d: d.current_url != initial_url) # 等待导出按钮重新加载可点击 export_button = wait.until(EC.element_to_be_clickable((By.XPATH, "//span[@class='export-csv']"))) export_button.click() # 等待当前文件下载完成,避免下一次操作中断 time.sleep(2) driver.close()
额外注意事项
- 境外网站访问延迟高,不要把等待时间设得太短,否则网络波动时很容易再次触发超时
- 连续1000次高频请求可能触发网站的反爬机制,可适当拉长两次操作的间隔,避免IP被临时封禁
- 运行前确保下载路径是本地真实存在的文件夹,否则Chrome会自动将文件存到默认下载目录
内容的提问来源于stack exchange,提问作者pbosani
相关产品推荐
相关产品推荐

