如何在Python中使用Selenium中的Chrome webdriver下载文件?

29

根据这里这里的帖子,我正在尝试在Selenium中使用Chrome浏览器驱动程序以便下载文件。目前的代码如下:

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

chrome_options = Options()
chrome_options.add_argument("--disable-extensions")
chrome_options.add_experimental_option("profile.default_content_settings.popups", 0)
chrome_options.add_experimental_option("download.prompt_for_download", "false")
chrome_options.add_experimental_option("download.default_directory", "/tmp")

driver = webdriver.Chrome(chrome_options=chrome_options)

但仅仅这样会导致以下错误:

WebDriverException: Message: unknown error: cannot parse capability: chromeOptions
from unknown error: unrecognized chrome option: download.default_directory
  (Driver info: chromedriver=2.24.417424 (c5c5ea873213ee72e3d0929b47482681555340c3),platform=Linux 4.10.0-37-generic x86_64)

那么如何解决这个问题呢?我需要使用这个“capability”吗?如果是的话,具体应该怎么做?

7个回答

43

试试这个。在Windows上执行

(如何使用Selenium Python绑定在Chrome中控制文件的下载)

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

options = Options()
options.add_experimental_option("prefs", {
  "download.default_directory": r"C:\Users\xxx\downloads\Test",
  "download.prompt_for_download": False,
  "download.directory_upgrade": True,
  "safebrowsing.enabled": True
})

3
好的,我会尽力进行翻译。以下是需要翻译的内容:是的,就是这样......我错误地使用了选项。很难找到正确的文档。除了 Stack Overflow 外,还有其他地方有记录吗? - Alex
11
请问您能否解释一下设置安全浏览的目的以及什么是目录升级? - Dkyc
6
确保使用 chrome_options=chrome_options 参数来启动 Chrome 浏览器驱动,而不是仅仅使用 webdriver.Chrome() - Ivan Chau
这似乎不太可靠...我开始收到下载提示来保存文件..如果有任何指针,将不胜感激! - Jay
1
实际上,仅 download.default_directorydownload.prompt_for_download 是必需的,截至 Chromium 97。 - Apteryx
显示剩余5条评论

6

我认为使用WebDriver保存任意文件(如图像)最简单的方法是执行JavaScript来保存文件。完全不需要配置!

我使用这个库FileSaver.js 来轻松保存文件并指定文件名。

from selenium import webdriver
import requests

FILE_SAVER_MIN_JS_URL = "https://raw.githubusercontent.com/eligrey/FileSaver.js/master/dist/FileSaver.min.js"

file_saver_min_js = requests.get(FILE_SAVER_MIN_JS_URL).content

chrome_options = webdriver.ChromeOptions()
driver = webdriver.Chrome('/usr/local/bin/chromedriver', options=chrome_options)

# Execute FileSaver.js in page's context
driver.execute_script(file_saver_min_js)

# Now you can use saveAs() function
download_script = f'''
    return fetch('https://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/so-logo.svg?v=a010291124bf',
        {{
            "credentials": "same-origin",
            "headers": {{"accept":"image/webp,image/apng,image/*,*/*;q=0.8","accept-language":"en-US,en;q=0.9"}},
            "referrerPolicy": "no-referrer-when-downgrade",
            "body": null,
            "method": "GET",
            "mode": "cors"
        }}
    ).then(resp => {{
        return resp.blob();
    }}).then(blob => {{
        saveAs(blob, 'stackoverflow_logo.svg');
    }});
    '''

driver.execute_script(download_script)
# Done! Your browser has saved an SVG image!

要绕过重复下载文件的警告或WebDriver服务器(非常适用于Docker),请使用driver.execute_script return readAsDataURL the with FileReader - Kelvin Ng

5

一些提示:

  1. chromium和chromedriver应该使用相同的版本。

    通常情况下,chromium包中应该包含chromedriver,您可以在安装目录中找到它。如果您正在使用ubuntu/debian,请执行dpkg -L chromium-chromedriver命令。

  2. 正确配置Chrome首选项。

    像Satish所说,使用options.add_experimental_option("prefs", ...)来配置selenium+chrome。但是有时候配置可能会随时间而改变。获取最新和可用的首选项的最佳方法是在chromium配置目录中进行检查。 例如,

    • 启动Xorg桌面中的chromium
    • 更改菜单中的设置
    • 退出chromium
    • ~/.config/chromium/Default/Preferences中找到实际的设置
    • 阅读它,挑选出您需要的确切选项。

在我的情况下,代码如下:

from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities

options = webdriver.ChromeOptions()
options.gpu = False
options.headless = True
options.add_experimental_option("prefs", {
    "download.default_directory" : "/data/books/chrome/",
    'profile.default_content_setting_values.automatic_downloads': 2,
    })

desired = options.to_capabilities()
desired['loggingPrefs'] = { 'performance': 'ALL'}
driver = webdriver.Chrome(desired_capabilities=desired)

Chromium的配置目录在哪里? - Mostafa

2
对于Mac OS中的Chrome浏览器,download.default_directory 对我来说无法正常工作,而幸运的是 savefile.default_directory 可以正常工作。
prefs = {
    "printing.print_preview_sticky_settings.appState": json.dumps(settings),
    "savefile.default_directory": "/Users/creative/python-apps",
    "download.prompt_for_download": False,
    "download.directory_upgrade": True,
    "download.safebrowsing.enabled": True
}

截至Chromium 97版本,只有download.default_directorydownload.prompt_for_download是必需的。 - Apteryx

1

你无法设置"download.default_directory"的原因之一可能是你在文件~/.config/user-dirs.dirs中有一个系统变量XDG_DOWNLOAD_DIR

你可以从该文件中删除变量,或者在运行程序之前将其设置为任何你喜欢的值。

我寻找解决方案已经两天了...

我的软件设置如下:

  • Ubuntu bionic,18.04.5 LTS
  • chromedriver.86.0.4240.22.lin64
  • Python 3.9
  • selenium 3.141.0
  • splinter 0.14.0

0

根据您的异常信息,您正在使用chromedriver=2.24.417424

您使用的Selenium和Chrome浏览器版本是什么?

我尝试了以下代码:

  • Selenium 3.6.0
  • chromedriver 2.33
  • Google Chrome 62.0.3202.62 (Official Build) (64-bit)

并且它可以正常工作:

from selenium import webdriver

download_dir = "/pathToDownloadDir"
chrome_options = webdriver.ChromeOptions()
preferences = {"download.default_directory": download_dir ,
               "directory_upgrade": True,
               "safebrowsing.enabled": True }
chrome_options.add_experimental_option("prefs", preferences)
driver = webdriver.Chrome(chrome_options=chrome_options,executable_path=r'/pathTo/chromedriver')

driver.get("urlFileToDownload");

请确保您使用的浏览器是由您的chromedriver支持的(从此处,应为Chrome v52-54)。


-1

你不能使用requests库吗?

如果可以的话,这里有一个例子:

import re
import requests

urls = [ '...' ]

for url in urls:
  # verify = False ==> for HTTPS requests without SSL certificates
  r = requests.get( url, allow_redirects = True, verify = False )

  cd = r.headers.get( 'content-disposition' )
  fa = re.findall( 'filename=(.+)', cd )

  if len( fa ) == 0:
    print( f'Error message: {link}' )
    continue

  filename = fa[ 0 ]

  f = open( os.path.join( 'desired_path', filename ), 'wb' )
  f.write( r.content )
  f.close()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接