Selenium WebDriver Python循环下载CSV中途崩溃问题求助
问题描述
我使用Selenium依次点击多个「Export (CSV)」链接下载多份CSV文件,但循环执行到中途时WebDriver突然停止工作,浏览器报错无网络并关闭驱动。已将chromedriver.exe放置在项目目录并配置路径,问题仍未解决。相关实现代码如下:
from selenium.webdriver.common.by import By from selenium.webdriver.chrome.options import Options import time import os import re new_directory = r"Z:\BI_Database_teste" for document in os.listdir(new_directory): os.remove(os.path.join(new_directory, document)) url = 'myPersonalURL' chrome_options = Options() chrome_options.add_argument('--headless') browser = webdriver.Chrome('chromedriver.exe', options=chrome_options) params = {'behavior': 'allow', 'downloadPath': new_directory} browser.execute_cdp_cmd('Page.setDownloadBehavior', params) browser.get(url) time.sleep(2) input_email = browser.find_element(By.ID, 'email') input_email.send_keys('myEmail') input_password = browser.find_element(By.ID, 'password') input_password.send_keys('myPassword') input_password.submit() input_question = browser.find_element(By.XPATH, '/html/body/div[2]/div[2]/form/table/tbody/tr[3]/td/table/tbody/tr[2]/td[2]').text answer_field = browser.find_element(By.XPATH, '/html/body/div[2]/div[2]/form/table/tbody/tr[3]/td/table/tbody/tr[3]/td[2]/input') if input_question == 'question': answer_field.send_keys('answer') elif input_question == 'question': answer_field.send_keys('answer') else: answer_field.send_keys('answer') time.sleep(2) answer_field.submit() time.sleep(4) links = browser.find_elements(By.LINK_TEXT, 'Export (CSV)') links_len = len(links) print(str(links_len) + ' BI Databases to Download') list_count = 0 for link in range(list_count, links_len): time.sleep(2) links[list_count].click() list_count = list_count + 1 print(str(list_count) + ' BI Databases downloaded') browser.quit() for file in os.listdir(new_directory): if file.startswith("PBI"): try: os.rename(os.path.join(new_directory, file), os.path.join(new_directory, re.sub('[0-9]', '', file))) except: pass print('BI Databases Download Successfully!')
DOM元素过期(Stale Element Reference)
点击下载链接后,页面可能发生局部刷新,初始获取的links列表中的元素会变成过期状态,后续调用links[list_count].click()会触发异常,导致驱动崩溃。
修复: 每次循环重新获取链接列表,避免使用过期元素:# 替换原循环部分代码 links_len = len(browser.find_elements(By.LINK_TEXT, 'Export (CSV)')) print(f'{links_len} BI Databases to Download') for list_count in range(links_len): # 每次循环重新定位当前要点击的链接 current_link = browser.find_elements(By.LINK_TEXT, 'Export (CSV)')[list_count] current_link.click() print(f'{list_count + 1} BI Databases downloaded') # 可根据实际情况添加短等待,避免请求过于频繁 time.sleep(1)无头模式配置不足
旧版无头Chrome的默认配置存在网络限制、内存不足等问题,容易触发无网络错误。
修复: 优化Chrome无头模式参数:chrome_options = Options() # 使用新版无头模式,兼容性更强 chrome_options.add_argument('--headless=new') chrome_options.add_argument('--disable-gpu') chrome_options.add_argument('--no-sandbox') # 解决Linux/Windows下的内存共享问题 chrome_options.add_argument('--disable-dev-shm-usage') chrome_options.add_argument('--enable-javascript') # 添加下载偏好设置,替代CDP命令(部分场景更稳定) prefs = { "download.default_directory": new_directory, "download.prompt_for_download": False, "download.directory_upgrade": True, "safebrowsing.enabled": True } chrome_options.add_experimental_option("prefs", prefs) browser = webdriver.Chrome('chromedriver.exe', options=chrome_options) browser.get(url)固定sleep导致的时序错误
依赖time.sleep()等待页面加载,网络波动时页面未就绪就执行操作,会引发元素找不到或操作失败,进而导致驱动异常。
修复: 改用Selenium显式等待,精准等待元素状态:# 先导入显式等待相关模块 from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC # 登录后等待下载链接出现 WebDriverWait(browser, 10).until( EC.presence_of_element_located((By.LINK_TEXT, 'Export (CSV)')) ) links_len = len(browser.find_elements(By.LINK_TEXT, 'Export (CSV)')) print(f'{links_len} BI Databases to Download') for list_count in range(links_len): # 等待当前链接可点击 current_link = WebDriverWait(browser, 10).until( EC.element_to_be_clickable((By.LINK_TEXT, 'Export (CSV)')) ) current_link.click() print(f'{list_count + 1} BI Databases downloaded')ChromeDriver与Chrome版本不兼容
即使chromedriver放在项目目录,若版本与本地Chrome浏览器不匹配,会导致驱动运行不稳定。
修复: 查看Chrome版本(设置→关于Chrome),下载对应版本的ChromeDriver替换现有文件。下载目录权限问题
目标目录Z:\BI_Database_teste可能无写入权限,下载失败后触发驱动异常。
修复: 检查目录读写权限,或临时更换为本地磁盘目录测试。
内容的提问来源于stack exchange,提问作者Jhonatta

