Python Selenium загружает изображения (jpeg, png) или PDF с помощью ChromeDriver

У меня есть скрипт Selenium на Python (использующий ChromeDriver в Windows), который извлекает ссылки для загрузки различных вложений (разных типов файлов) со страницы, а затем открывает эти ссылки для загрузки вложений. Это прекрасно работает для типов файлов, которые 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 ответа

Вместо того, чтобы полагаться на определенные опции браузера / драйвера, я бы реализовал более общее решение, используя URL-адрес изображения для выполнения загрузки.

Вы можете получить 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")

Удачи, счастливого взлома:)

С участием 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()

Обратите внимание, что функция может быть улучшена таким образом, чтобы можно было сохранить структуру каталогов.

Вот еще один простой способ, но ответ @Pitto выше немного более лаконичен.

      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)
Другие вопросы по тегам