Selenium脚本偶尔运行失败是什么原因?能否循环执行直至运行成功?
Selenium函数重试执行方案
可以实现,通过异常捕获结合循环重试的逻辑即可达成需求,同时将原有代码中的固定等待替换为Selenium显式等待,可以大幅降低元素未加载导致的偶发报错概率。
改造后完整代码
import time from selenium import webdriver from selenium.webdriver.support.ui import Select from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By from selenium.common.exceptions import ( NoSuchElementException, ElementClickInterceptedException, TimeoutException ) url = "https://www.coordinador.cl/operacion/graficos/operacion-real/generacion-real-del-sistema/" # 自定义最大重试次数,避免无限循环 MAX_RETRY = 5 def download_generation(month, year, driver): # 初始化显式等待对象,最长等待时长可自行调整 wait = WebDriverWait(driver, 10) driver.get(url) # 等待文件类型选择按钮可点击后再操作 tipo_xlsx = wait.until(EC.element_to_be_clickable((By.ID, 'tipo-xlsx'))) tipo_xlsx.click() tipo_xlsx.click() # 等待日期选择器加载完成 date_picker = wait.until(EC.element_to_be_clickable((By.ID, 'datepicker777-9761_2'))) date_picker.click() # 选择月份 dropdown_month = Select(wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'ui-datepicker-month')))) dropdown_month.select_by_visible_text(month) # 选择年份 dropdown_year = Select(wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'ui-datepicker-year')))) dropdown_year.select_by_visible_text(year) # 关闭日期选择器 close_btn = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, '#ui-datepicker-div > div.ui-datepicker-buttonpane.ui-widget-content > button.ui-datepicker-close.ui-state-default.ui-priority-primary.ui-corner-all'))) close_btn.click() # 点击下载按钮 download_btn = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, '#Collapse2 > div > article > div.row.margin-top-3.cen_box-filter > div > div > form > div > div:nth-child(4) > a'))) driver.execute_script("arguments[0].click();", download_btn) # 带重试逻辑的调用函数 def run_with_retry(month, year, driver): for retry_cnt in range(MAX_RETRY): try: download_generation(month, year, driver) # 无异常则直接返回执行成功 return True except (NoSuchElementException, ElementClickInterceptedException, TimeoutException) as e: print(f"第{retry_cnt+1}次执行失败,错误信息:{str(e)},即将重试") # 重试前刷新页面清除上一次操作残留 driver.refresh() time.sleep(2) print(f"累计重试{MAX_RETRY}次,执行失败") return False
注意事项
- 你可以把实际运行中遇到的其他异常类型补充到except的捕获列表中,避免遗漏报错导致重试逻辑失效
- 若需要确保文件完整下载再判定成功,可以额外增加校验下载目录下对应文件是否存在、文件大小是否符合预期的逻辑
- MAX_RETRY参数可根据实际使用场景调整,设置为3-5次即可覆盖绝大多数偶发异常场景
内容的提问来源于stack exchange,提问作者Arturo M
相关产品推荐
相关产品推荐

