Python Selenium使用ChromeDriver下载图像(jpeg,png)或PDF

时间:2018-04-03 10:10:40

标签: python selenium selenium-webdriver selenium-chromedriver

我在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来完成吗?

任何帮助都将受到高度赞赏。

3 个答案:

答案 0 :(得分:2)

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

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

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

玩得开心,快乐的黑客攻击:)

答案 1 :(得分:0)

使用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

让我们从Google主页上将一些图像下载到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()

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

答案 2 :(得分:0)

这是另一种简单的方法,但 @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)