Как делать скриншоты веб-страницы на python

Admin Mac OS, Python, Ubuntu

Делать скриншоты будем через браузер Chrome (можно любой другой) и модуль selenium на python.

Скриншоты будут делаться на Ubuntu 20.04. Однако это не зависит от операционной системы и будет работать также на Mac Os или Windows (но работу здесь не проверял, это не точно).

Инструкция будет приведена именно под Ubuntu, потому что на Mac OS все проще. Например, не надо устанавливать Chrome через командную строку или запускать его в режиме скрытности.

Устанавливаем Chrome

Скачиваем:

wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb

Устанавливаем (при установке вводим пароль пользователя Linux):

sudo apt install ./google-chrome-stable_current_amd64.deb

Устанавливаем Chromium

Как альтернатива хрому:

sudo apt-get install chromium-browser

Устанавливаем selenium

Установка из виртуальной среды:

pip install selenium

Устанавливаем драйвер chromedriver

В установке драйвера есть одна особенность. Он должен быть той же версии, что и браузер. А т.к. браузер постоянно обновляется, то каждый раз приходится искать к нему нужный драйвер. Чтобы это избежать можно использовать webdriver-manager.

Установка:

pip install webdriver-manager

Установка драйвера вручную

Иногда вышеописанный метод не находит браузер. Ошибки, которые возникают есть ниже в статье. У меня так и не получилось запустить Google Chrome через webdriver-manager.

а)
Установить драйвер с официального сайта:

https://chromedriver.chromium.org/

Перенести его в директорию исполняемых файлов:

mv chromedriver /usr/local/bin/

Назначить права на выполнение:

chmod +x /usr/local/bin/chromedriver

б)
Также можно попробовать для установки драйвера использовать команду:

sudo apt install chromium-chromedriver

Дальше в коде использовать:

driver = webdriver.Chrome()

или с указанием пути, если не находит:

driver = webdriver.Chrome('/usr/local/bin/chromedriver')

Дебаг

Если webdriver отказывается видеть браузер или драйвер, могут помочь некоторые команды.

Узнать какая версия установлена:

chromedriver -v
google-chrome -version

Узнать местоположения браузера:

whereis chromium
whereis chromium-browser
whereis google-chrome

Конечный код

По хорошему было бы ограничиться одним ChromeDriverManager, но в реальном мире не всегда работает то что описано в доках. Как выше писал, у меня не заработал Google Chrome на Ubuntu 20.04. А вернее был сделан 1 скриншот, а затем больше он его не видел.

Поэтому я установил Chromium, нашел путь к драйверу через команду whereis chromium, затем закомментировал ChromeDriverManager. А вместо этого указал путь к нему через свойство executable_path.

Кроме этого применил переменную окружения. На Mac OS (в локальной разработке) у меня все хорошо отрабатывало, я оставил ChromeDriverManager, а на удаленном сервере использовал вышеописанный метод.

Переменную окружения можно поставить в конфигурационных файлах Flask таким образом:

os.environ['SERVER_ENV'] = 'local'

Весь кода получился таким:

import os
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from webdriver_manager.chrome import ChromeDriverManager
from webdriver_manager.utils import ChromeType

def save_screenshot(link, img):
    # Сохранить только видимую часть открытой страницы
    try:
        chrome_options = Options()
        chrome_options.add_argument("--headless")
        chrome_options.add_argument('--no-sandbox')

        if os.environ.get('SERVER_ENV') == 'local':
            driver = webdriver.Chrome(ChromeDriverManager(chrome_type=ChromeType.GOOGLE, cache_valid_range=5).install(), options=chrome_options)
        else:
            # driver = webdriver.Chrome(ChromeDriverManager(chrome_type=ChromeType.CHROMIUM, cache_valid_range=5).install(), options=chrome_options)
            driver = webdriver.Chrome(executable_path='/snap/bin/chromium.chromedriver', options=chrome_options)

        driver.get(link)
        driver.save_screenshot()
        driver.quit()

        return True
    except Exception as e:
        print('Ошибка при сохранении скриншота: {}'.format(e))

cache_valid_range=5 — этот параметр означает кэш в днях. На это количество дней будет кэшироваться драйвер прежде чем снова пойти искать новую версию и устанавливать её.

Ошибка: This version of ChromeDriver only supports Chrome version

Эта ошибка возникает, если версии драйвера и браузера не совпадают:

raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.SessionNotCreatedException: Message: session not created: This version of ChromeDriver only supports Chrome version 85

Ошибка: ubuntu The process started from chrome location

На сервере Ubuntu может возникнуть ошибка:

ubuntu The process started from chrome location /usr/bin/google-chrome is no longer running, so ChromeDriver is assuming that Chrome has crashed.

Если запуск идет из командной строки, то надо добавить запуск браузера в скрытом режиме. Это делается добавлением опций:

chrome_options = Options()
chrome_options.add_argument("--headless")
chrome_options.add_argument('--no-sandbox')

Ошибка: ValueError: Could not get version for Chrome

Еще одна ошибка:

ValueError: Could not get version for Chrome with this command: google-chrome

Может возникнуть если не указано свойство chrome_type=ChromeType.GOOGLE, но помогает не всегда.

Ошибка: google-chrome: not found

Эту ошибку на Ubuntu 20.04 пофиксить не получилось.

/bin/sh: 1: google-chrome: not found
/bin/sh: 1: google-chrome-stable: not found
Could not get version for Chrome with this command: google-chrome —version || google-chrome-stable —version
subprocess 931222 exited with code 127

По непонятным причинам отказывался видеть браузер, хотя тот был установлен и права на его выполнение поставлены. Решено было это альтернативой, об этом написано выше в статье.

Оптимизация изображений

Статья по оптимизации изображений на python.

У сайта нет цели самоокупаться, поэтому на сайте нет рекламы. Но если вам пригодилась информация, можете лайкнуть страницу, оставить комментарий или отправить мне подарок на чашечку кофе.

Добавить комментарий

Напишите свой комментарий, если вам есть что добавить/поправить/спросить по теме текущей статьи:
"Как делать скриншоты веб-страницы на python"