【问题标题】:How to use chrome webdriver in selenium to download files in python?如何在 selenium 中使用 chrome webdriver 在 python 中下载文件?
【发布时间】:2018-04-06 19:58:55
【问题描述】:

根据herehere 的帖子,我正在尝试在 selenium 中使用 chrome webdriver 来下载文件。这是到目前为止的代码

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)

那么如何解决这个问题?我必须使用这种“能力”吗?如果有,具体是怎样的?

【问题讨论】:

    标签: python google-chrome selenium


    【解决方案1】:

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

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

    我这两天一直在寻找解决方案...

    我的软件集:

    • Ubuntu 仿生,18.04.5 LTS
    • chromedriver.86.0.4240.22.lin64
    • Python 3.9
    • 硒 3.141.0
    • 分裂0.14.0

    【讨论】:

      【解决方案2】:

      你不能使用requests lib吗?

      如果是这样,这里有一个例子:

      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()
      

      【讨论】:

        【解决方案3】:

        对于 mac os 中的 chrome,download.default 目录对我不起作用,幸运的是 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
        }
        

        【讨论】:

          【解决方案4】:

          我认为使用 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
          【解决方案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
            • 在菜单中更改设置
            • 戒掉铬
            • 找出~/.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)
          

          【讨论】:

          • 铬配置目录在哪里?
          【解决方案6】:

          从您的例外情况来看,您使用的是chromedriver=2.24.417424

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

          我尝试了以下代码:

          • 硒 3.6.0
          • chromedriver 2.33
          • Google Chrome 62.0.3202.62(官方版本)(64 位)

          它有效:

          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 支持(来自here,应该是Chrome v52-54)。

          【讨论】:

            【解决方案7】:

            试试这个。在windows上执行

            (How to control the download of files with Selenium Python bindings in 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
            })
            

            【讨论】:

            • 是的,就是这样...我以错误的方式使用了这些选项。很难获得正确的文档。除了 SO...之外,是否有记录?
            • 如果您愿意解释一下设置安全浏览的目的是什么以及什么是目录升级?
            • 确保driver = webdriver.Chrome(chrome_options=chrome_options) 而不仅仅是driver = webdriver.Chrome()
            • 这似乎不可靠......我已经开始收到下载提示以保存文件......不胜感激任何指针!
            • 最佳猜测;如果雇主管理的 chrome 不允许我手动设置这些设置,这将不起作用。 :(
            猜你喜欢
            • 1970-01-01
            • 2015-09-12
            • 2019-02-22
            • 2017-08-26
            • 1970-01-01
            • 2017-11-04
            • 2016-04-26
            相关资源
            最近更新 更多