【问题标题】:Python Selenium download images (jpeg, png) or PDF using ChromeDriverPython Selenium 使用 ChromeDriver 下载图像(jpeg、png)或 PDF
【发布时间】:2018-09-12 15:00:44
【问题描述】:

我有一个 Python 中的 Selenium 脚本(在 Windows 上使用 ChromeDriver),它从页面获取各种附件(不同文件类型)的下载链接,然后打开这些链接以下载附件。这适用于 ChromeDriver 默认下载时无法预览的文件类型。但是默认情况下会预览图像(JPEG、PNG)和 PDF,因此不会自动下载。

我目前使用的 ChromeDriver 选项(适用于不可预览的文件):

chrome_options = webdriver.ChromeOptions()
prefs = {'download.default_directory' : 'custom_download_dir'}
chrome_options.add_experimental_option('prefs', prefs)
driver = webdriver.Chrome("./chromedriver.exe", chrome_options=chrome_options)

这会将文件下载到“custom_download_dir”,没有问题。但可预览的文件只是在 ChromeDriver 实例中预览,而不是下载。

是否有任何 ChromeDriver 设置可以禁用此预览行为并直接下载所有文件而不考虑扩展名?

如果不能,例如可以使用 Firefox 来完成吗?

【问题讨论】:

    标签: python selenium selenium-webdriver selenium-chromedriver


    【解决方案1】:

    这是另一种简单的方式,但@Pitto's answer above 稍微简洁一些。

    import requests
    
    webelement_img = ff.find_element(By.XPATH, '//img')
    url = webelement_img.get_attribute('src') or 'https://someimages.com/path-to-image.jpg'
    data = requests.get(url).content
    local_filename = 'filename_on_your_computer.jpg'
    
    with open (local_filename, 'wb') as f:
        f.write(data)
    

    【讨论】:

      【解决方案2】:

      我不会依赖特定的浏览器/驱动程序选项,而是使用图像 url 来实现更通用的解决方案来执行下载。

      您可以使用类似的代码获取图片网址:

      driver.find_element_by_id("your-image-id").get_attribute("src")
      

      然后我会使用例如 urllib 下载图像。

      以下是 Python2 的一些伪代码:

      import urllib
      
      url = driver.find_element_by_id("your-image-id").get_attribute("src")
      urllib.urlretrieve(url, "local-filename.jpg")
      

      Python3 也一样:

      import urllib.request
      
      url = driver.find_element_by_id("your-image-id").get_attribute("src")
      urllib.request.urlretrieve(url, "local-filename.jpg")
      

      在评论后编辑,这只是另一个关于如何在知道文件 URL 后下载文件的示例:

      import requests
      from PIL import Image
      from io import StringIO
      
      image_name = 'image.jpg'
      url = 'http://example.com/image.jpg'
      
      r = requests.get(url)
      
      i = Image.open(StringIO(r.content))
      i.save(image_name)
      

      【讨论】:

      • 问题是查看图片我需要认证。我尝试使用 Python Requests 库,它需要 Kerberos 身份验证,我尝试提供凭据并使用 Python Kerberos 库,但它不起作用。我可以在 Selenium WebDriver 上查看它,所以我正在寻找一种通过 WebDriver 实例本身下载的方法。
      • 在谷歌浏览器上禁用自动打开图像怎么样?这可能会触发自动下载...presentermedia.com/blog/2013/10/…
      • 是否有使用 Python 中的 Chrome WebDriver 设置禁用自动打开的选项?
      • @halfer 显然,urlretrieve 是遗留问题。有没有更新、更好的方法来做到这一点?
      • 没有问题@oldboy。 Pitto,感谢您进行编辑 - 不要忘记引起人们的注意。人们只有在订阅您的答案时才能看到更改,因此在这种情况下可能会错过。
      【解决方案3】:

      使用selenium-wire库,可以通过ChromeDriver下载图片。

      我已经定义了以下函数来解析每个请求,并在必要时将请求正文保存到文件中。

      import os
      from mimetypes import guess_extension
      from seleniumwire import webdriver
      
      def download_assets(requests, asset_dir="temp", default_fname="untitled", exts=[".png", ".jpeg", ".jpg", ".svg", ".gif", ".pdf", ".ico"]):
          asset_list = {}
          for req_idx, request in enumerate(requests):
              # request.headers
              # request.response.body is the raw response body in bytes
              ext = guess_extension(request.response.headers['Content-Type'].split(';')[0].strip())
              if ext is None or ext not in exts:
                  #Don't know the file extention, or not in the whitelist
                  continue
      
              # Construct a filename
              fname = os.path.basename(request.url.split('?')[0])
              fname = "".join(x for x in fname if (x.isalnum() or x in "._- "))
              if fname == "":
                  fname = f"{default_fname}_{req_idx}"
              if not fname.endswith(ext):
                  fname = f"{fname}{ext}"
              fpath = os.path.join(asset_dir, fname)
      
              # Save the file
              print(f"{request.url} -> {fpath}")
              asset_list[fpath] = request.url
              with open(fpath, "wb") as file:
                  file.write(request.response.body)
          return asset_list
      

      让我们从谷歌主页下载一些图片到temp文件夹。

      # Create a new instance of the Chrome/Firefox driver
      driver = webdriver.Chrome()
      
      # Go to the Google home page
      driver.get('https://www.google.com')
      
      # Download content to temp folder
      asset_dir = "temp"
      os.makedirs(asset_dir, exist_ok=True)
      download_assets(driver.requests, asset_dir=asset_dir)
      
      driver.close()
      

      注意,功能可以改进,目录结构也可以保留。

      【讨论】:

        猜你喜欢
        • 2021-11-16
        • 1970-01-01
        • 2019-05-04
        • 1970-01-01
        • 1970-01-01
        • 2013-06-26
        • 1970-01-01
        • 1970-01-01
        • 2011-01-30
        相关资源
        最近更新 更多