如何在 Selenium 中正确启用并管理文件下载功能

1次阅读

如何在 Selenium 中正确启用并管理文件下载功能

Selenium 4.12+ 引入了原生下载管理能力,但需显式启用 enable_downloads 选项并配合 Grid 配置,否则调用 get_downloadable_files() 会报错“must enable downloads”。本文详解完整配置流程、代码示例及关键注意事项。

.selenium 4.12+ 引入了原生下载管理能力,但需显式启用 `enable_downloads` 选项并配合 grid 配置,否则调用 `get_downloadable_files()` 会报错“must enable downloads”。本文详解完整配置流程、代码示例及关键注意事项。

在 Selenium 中实现可靠、可编程的文件下载(尤其是 PDF、CSV 等非导航型资源),不能仅依赖传统 download.default_directory 偏好设置——该方式无法被 get_downloadable_files() 识别,且易受浏览器沙箱、弹窗拦截或跨域限制干扰。自 Selenium 4.12 起,官方提供了服务端托管下载(Managed Downloads)机制,它将下载行为纳入 WebDriver 协议层统一管理,支持主动枚举、校验与下载控制。

✅ 正确启用下载管理的三要素

要成功使用 driver.get_downloadable_files() 和 driver.download_file(),必须同时满足以下三项条件:

  1. 客户端启用:在 chromeOptions(或其他浏览器 Options)中设置 options.enable_downloads = True;
  2. 服务端启用:若使用 Selenium Grid(本地 standalone 或远程 node),启动时必须添加 –enable-managed-downloads true 参数;
  3. 不冲突旧配置:移除或禁用所有可能干扰托管下载的实验性偏好项(如 “download.default_directory”、”download.prompt_for_download”),这些字段在托管模式下由 Selenium 自动处理,手动设置反而会导致未定义行为。

⚠️ 注意:enable_downloads = True 仅对 webdriver.Remote 有效(即连接 Grid/standalone server 的场景)。若直接使用 webdriver.Chrome() 本地驱动,该属性被忽略,且 get_downloadable_files() 不可用——这是当前 Selenium 的设计限制。

? 完整可运行示例(Remote WebDriver)

from selenium import webdriver from selenium.webdriver.chrome.options import Options  # 1. 配置 ChromeOptions 并启用托管下载 options = Options() options.enable_downloads = True  # ← 关键!必须设为 True  # 可选:指定 Chrome 二进制路径或禁用沙箱等(根据环境调整) # options.binary_location = "/usr/bin/google-chrome" # options.add_argument("--no-sandbox")  # 2. 启动 Remote WebDriver(连接本地 standalone server) # 假设已通过命令行启动:java -jar selenium-server-4.18.0.jar standalone --enable-managed-downloads true driver = webdriver.Remote(     command_executor="http://localhost:4444",  # 默认 standalone 地址     options=options )  try:     # 3. 导航到含下载链接的页面(例如一个 PDF 下载按钮)     driver.get("https://example.com/resume.pdf")  # 或含 <a download> 的 HTML 页面      # 4. 获取当前可下载文件列表(返回 DownloadableFile 对象列表)     downloadable_files = driver.get_downloadable_files()     print(f"发现 {len(downloadable_files)} 个待下载文件")      if downloadable_files:         # 5. 下载第一个文件到指定目录(自动创建子目录,支持绝对/相对路径)         target_dir = "/Users/abderrahim/Documents/cv_apec"         downloaded_path = driver.download_file(downloadable_files[0], target_dir)         print(f"✅ 已保存至: {downloaded_path}")  finally:     driver.quit()

? 验证与排错要点

  • Grid 启动命令必须包含 –enable-managed-downloads true

    java -jar selenium-server-4.18.0.jar standalone    --host 127.0.0.1    --port 4444    --enable-managed-downloads true

    缺少此参数将直接触发 WebDriverException: You must enable downloads… 错误。

  • 避免混合使用旧下载配置
    删除或注释掉如下代码(它们与托管下载互斥):

    # ❌ 不要再设置这些(在 enable_downloads=True 时无效甚至有害) # options.add_experimental_option("prefs", { #     "download.default_directory": r"/path/to/dir", #     "download.prompt_for_download": False, # })
  • 文件可见性要求:get_downloadable_files() 仅返回当前浏览器上下文内已触发但尚未完成的下载任务(例如点击 或 window.open(‘file.pdf’) 后)。它不会扫描磁盘目录,也不支持“预设监听 URL 模式”。

  • 下载路径安全性:download_file(file, target_dir) 中的 target_dir 必须是 WebDriver 服务端可写路径(若 Grid 运行在 docker 或远程服务器上,请确保该路径存在且权限正确)。

✅ 总结

Selenium 的托管下载是面向自动化测试与数据采集场景的现代化解决方案,它解耦了浏览器配置与下载逻辑,提升了稳定性和可观测性。请始终遵循「客户端启用 + 服务端启用 + 避免旧配置」三位一体原则。对于纯本地调试需求,可暂用传统 requests + selenium 提取 URL 的组合方案作为补充;但涉及复杂交互(如登录后动态生成下载 Token),托管下载仍是唯一健壮选择。

text=ZqhQzanResources