Selenium无头模式无法正确下载文件,启用指定方法仍异常
解决方案:Selenium无头模式下载文件异常问题
问题根源
你遇到的问题核心是Page.setDownloadBehavior命令干扰了浏览器默认的下载逻辑——这个命令会强制把服务器返回的响应直接保存到指定路径,但如果服务器返回的是跳转或需要浏览器解析的下载请求,就会错误地把当前页面的xhtml内容存成文件,而非预期的目标下载文件。这也是为什么非无头模式下调用该方法也会出问题的原因。
具体修复方案
1. 改用ChromeOptions直接配置下载偏好,弃用enable_download_headless方法
直接通过Chrome的偏好设置指定下载路径,这是更稳定的原生方式,不会干扰浏览器的默认下载流程:
from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By import os import time def excerpt(): options = webdriver.ChromeOptions() # 启用新版无头模式(Chrome 112+推荐,兼容性更好) options.add_argument("--headless=new") user_agent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.198 Safari/537.36' options.add_argument(f'user-agent={user_agent}') options.add_argument('--ignore-certificate-errors') options.add_argument('--allow-running-insecure-content') options.add_argument("--window-size=1920,1080") # 配置下载相关偏好 download_dir = "/Download/Path/" prefs = { "download.default_directory": download_dir, "download.prompt_for_download": False, "profile.default_content_settings.popups": 0, "safebrowsing.enabled": True } options.add_experimental_option("prefs", prefs) driver_path = "path/to/chromedriver" driver = webdriver.Chrome(driver_path, options=options) driver.get("https://www.xxxxx.de/xxx/chargeinfo.xhtml") # 用显式等待替代time.sleep,更可靠 WebDriverWait(driver, 20).until( EC.element_to_be_clickable((By.XPATH, "//span[@class='ui-button-text ui-c' and contains(text(), 'Download')]")) ).click() # 可选:等待文件下载完成(根据实际文件后缀调整判断条件) while not any(f.endswith(".csv") or f.endswith(".xlsx") for f in os.listdir(download_dir)): time.sleep(1) driver.quit()
2. 确保Chrome与ChromeDriver版本完全匹配
旧版本的Chrome/ChromeDriver在无头模式下的下载逻辑存在已知bug,去ChromeDriver官网下载和你当前Chrome版本完全一致的驱动,避免版本不兼容导致的异常。
3. 绕过浏览器下载,直接用requests获取文件
如果上述方法仍无效,可直接提取真实下载链接,用requests库下载,绕过浏览器的下载流程(适合处理JS生成的下载链接):
# 点击下载按钮前,先获取真实下载URL(根据页面实际逻辑调整) download_url = driver.execute_script("return document.querySelector('你的下载按钮选择器').getAttribute('href')") # 复制浏览器会话的cookies到requests import requests session = requests.Session() for cookie in driver.get_cookies(): session.cookies.set(cookie['name'], cookie['value']) # 下载文件 response = session.get(download_url) with open(os.path.join(download_dir, "目标文件名.ext"), "wb") as f: f.write(response.content)
内容的提问来源于stack exchange,提问作者Boglinger
相关产品推荐
相关产品推荐

