如何通过Selenium(Chrome+Python)获取下载中的文件名
使用Selenium + Python 获取Chrome正在下载的文件名(无需等待完成)
可以实现,核心是利用Chrome DevTools Protocol (CDP) 监听浏览器的下载事件或网络响应,在下载开始时直接提取文件名,无需等待下载完成。
实现方案
Chrome的CDP提供了与浏览器底层交互的接口,我们可以通过Selenium的execute_cdp_cmd方法调用这些接口,捕获下载起始事件并解析文件名。
方法1:监听Download.downloadWillBegin事件(推荐,Chrome 81+支持)
这个事件会在浏览器准备开始下载时触发,直接返回建议的文件名,无需手动解析响应头:
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.chrome.options import Options import json def capture_download_filename(driver): # 读取性能日志,筛选下载起始事件 performance_logs = driver.get_log('performance') for log_entry in performance_logs: log_data = json.loads(log_entry['message'])['message'] if log_data['method'] == 'Download.downloadWillBegin': return log_data['params']['suggestedFilename'] return None # 配置Chrome浏览器 chrome_options = Options() chrome_options.add_experimental_option('excludeSwitches', ['enable-logging']) # 可选:关闭下载弹窗,指定下载路径 chrome_options.add_experimental_option('prefs', { 'download.default_directory': '/Users/yourname/Downloads', 'download.prompt_for_download': False, 'plugins.always_open_pdf_externally': True # 如果是PDF下载,避免在浏览器打开 }) # 初始化驱动并启用CDP下载监听 driver = webdriver.Chrome(options=chrome_options) driver.execute_cdp_cmd('Download.enable', {}) # 触发下载操作(示例:点击下载按钮) driver.get('https://example.com/your-download-page') driver.find_element(By.CSS_SELECTOR, '.download-button').click() # 获取正在下载的文件名 downloading_filename = capture_download_filename(driver) if downloading_filename: print(f"正在下载的文件:{downloading_filename}") else: print("未检测到下载请求") # 后续业务逻辑... # driver.quit()
方法2:解析Network.responseReceived响应头(兼容旧版Chrome)
如果你的Chrome版本不支持Download域,可以通过监听网络响应,从Content-Disposition头中提取文件名:
def get_filename_from_response(driver): performance_logs = driver.get_log('performance') for log_entry in performance_logs: log_data = json.loads(log_entry['message'])['message'] if log_data['method'] == 'Network.responseReceived': response_headers = log_data['params']['response']['headers'] # 检查是否为下载类型的响应 if 'Content-Disposition' in response_headers: cd_header = response_headers['Content-Disposition'] if 'filename=' in cd_header: # 处理带引号或不带引号的文件名格式 filename = cd_header.split('filename=')[-1].strip('"') return filename return None # 使用方式和方法1类似,只需替换capture_download_filename为get_filename_from_response
注意事项
- 确保Chrome浏览器和ChromeDriver版本严格匹配,CDP命令的兼容性依赖版本
- 必须在触发下载操作之前调用
driver.execute_cdp_cmd('Download.enable', {})或启用Network监听,否则会错过事件 - 对于通过JavaScript动态触发的下载,要保证监听逻辑在下载触发前已生效
- 如果下载链接是直接跳转的(而非按钮点击),可以在访问该链接后立即执行文件名捕获逻辑
内容的提问来源于stack exchange,提问作者Blitz
相关产品推荐
相关产品推荐

