Python中使用Selenium+Firefox直接下载文件驱动卡住如何解决?
根因分析
你遇到的阻塞问题核心原因是:Geckodriver 执行 driver.get() 方法时,默认会等待浏览器触发「页面加载完成」事件才会返回继续执行后续代码。而直接访问下载类URL时,浏览器不会渲染DOM页面,也不会触发标准的页面加载完成信号,导致驱动一直处于等待状态,永远执行不到后续的driver.close()。
这个行为和你的下载配置项无关,是Selenium默认页面加载等待机制的固有特性。
适配你业务场景的解决方案
你需要直接访问拼接URL,无法通过点击元素触发下载,可以用以下两种方案解决:
方案1:修改页面加载策略,跳过加载等待
将Firefox的页面加载策略设置为none,驱动不会等待任何页面加载信号,调用driver.get()后会立刻返回,你再自行监控下载目录的文件状态判断是否下载完成即可。
示例代码:
from selenium import webdriver from selenium.webdriver.firefox.options import Options import os import time # 原有FirefoxProfile配置不变 fp = webdriver.FirefoxProfile() fp.set_preference("browser.download.folderList", 2) fp.set_preference("browser.download.dir", downloaddir) fp.set_preference("browser.download.useDownloadDir", True) fp.set_preference("browser.download.viewableInternally.enabledTypes", "") fp.set_preference("browser.download.manager.useWindow", False) fp.set_preference("browser.download.manager.showWhenStarting", False) fp.set_preference("browser.download.manager.closeWhenDone", True) fp.set_preference('browser.helperApps.neverAsk.openFile', "application/zip") fp.set_preference("browser.helperApps.neverAsk.saveToDisk", "application/zip") fp.set_preference("pdfjs.disabled", True) # 新增页面加载策略配置 options = Options() options.page_load_strategy = 'none' driver = webdriver.Firefox(firefox_profile=fp, options=options) driver.get('http://speedtest.tele2.net/10MB.zip') # 自行监控下载完成:判断下载目录下是否存在.part/.tmp临时文件 while True: temp_files = [f for f in os.listdir(downloaddir) if f.endswith('.part') or f.endswith('.tmp')] if not temp_files: break time.sleep(1) # 下载完成后再关闭驱动 driver.close() driver.quit()
方案2:复用Selenium会话,用HTTP请求直接下载
该方案更适合直接访问拼接下载URL的场景,完全规避Selenium下载的阻塞问题:直接从Selenium驱动中提取当前会话的Cookie、请求头等鉴权信息,用requests库发起下载请求,不需要依赖浏览器的下载逻辑,性能和稳定性更高。
示例代码片段:
import requests # driver已经完成登录等前置操作后,提取cookie cookies = driver.get_cookies() session = requests.Session() for cookie in cookies: session.cookies.set(cookie['name'], cookie['value']) # 直接用requests下载拼接好的URL resp = session.get("你的拼接下载URL", stream=True) with open(f"{downloaddir}/target.zip", "wb") as f: for chunk in resp.iter_content(chunk_size=1024): if chunk: f.write(chunk)
关于原生下载方案的疑问
Selenium本身没有原生的、专门用于直接下载文件的API,它的核心定位是模拟用户和浏览器页面的交互行为,文件下载只是浏览器的附带功能,没有做针对性的适配,不存在完全无报错的原生下载方案,所有下载场景都需要配合额外的逻辑适配。
内容的提问来源于stack exchange,提问作者vbargl
相关产品推荐
相关产品推荐

