Делаем скриншоты страниц в безголовом браузере
Безголовый (от английского Headless) – это браузер, в котором отсутствует графический пользовательский интерфейс. Фактически, это способ навигации в интернете с помощью командной строки.

Стандартный и безголовый браузеры
Безголовые браузеры полезны для тестирования сайтов. Они позволяют переходить на страницу и выполнять действия без необходимости вручную открывать браузер и нажимать на кнопки. Еще одно применение безголовых браузеров – динамическое создание скриншотов веб-страниц.
Чего я пытаюсь добиться?
Несколько лет назад я написала код для встраивания данных с caniuse для любого конкретного свойства. Посмотрите пример того, как это выглядит.
Но для отображения данных всегда требовался JavaScript. Если Javascript отключен в браузере или если сеть работает слишком медленно, вот что мы получаем:

Потому что до тех пор, пока скрипт не сгенерирует iframe, код для встраивания будет выглядеть так:
<p class="ciu_embed" data-feature="css-grid" data-periods="future_1,current,past_1,past_2" data-accessible-colours="false">
<a href="http://caniuse.com/#feat=css-grid">Могу ли я использовать CSS-Grid?</a>
</p>
Я пришла к выводу, что лучшим решением будет программное создание скриншота страницы со встраиванием. Это можно сделать, используя безголовый браузер, а потом добавить скриншот в запасной (fallback) код.
Для этого необходимо выполнить следующие действия:
- Сделать скриншот страницы для встраивания.
- Создать API для обработки изображений и загрузить изображение в Cloudinary.
- Обновить запасной код, чтобы он содержал скриншот.
В этой статье я расскажу об использовании безголового браузера для получения скриншота страницы.
Безголовый Chrome
Начиная с версии 59, безголовый Chrome доступен с помощью команды chrome. Чтобы получить DOM-содержимое страницы, используется флаг --dump-dom .
chrome --headless --disable-gpu --dump-dom https://bitsofco.de
Чтобы сделать скриншот, используем вместо него флаг --screenshot .
chrome --headless --disable-gpu --screenshot https://bitsofco.de
Puppeteer – безголовый Chrome на node-интерфейсе API
Puppeteer позволяет использовать безголовый Chrome почти везде. Чтобы сделать скриншот с помощью Puppeteer, нужно:
- Запустить браузер.
- Открыть новую страницу.
- Перейти к выбранному URL-адресу.
- Сделать скриншот.
const puppeteer = require('puppeteer');
(async () => {
// 1. 1. Запустите браузер
const browser = await puppeteer.launch();
// 2. 1. Откройте новую страницу
const page = await browser.newPage();
// 3. 1. Перейдите к выбранному URL
await page.goto('https://bitsofco.de');
// 4. 1. Сделайте скриншот
await page.screenshot({path: 'screenshot.png'});
await browser.close();
})();
С помощью этого кода мы сделали скриншот страницы https://bitsofco.de и сохранили его как PNG-файл в текущей папке под именем screenshot.png .
Делаем скриншот встраиваемых данных
В моем случае нужно было сделать скриншот встраиваемых данных и сохранить его как бинарный, чтобы позже загрузить в Cloudinary. Для этого мне пришлось внести несколько изменений в пример, представленный выше.
Определение области просмотра браузера
По умолчанию Puppeteer использует размер окна браузера 800px на 600px. Чтобы изменить это, можно вручную установить высоту и ширину области просмотра в параметрах, переданных puppeteer.launch ().
const browser = await puppeteer.launch({
defaultViewport: {
width: 800,
height: 500,
isLandscape: true
}
});
Также можно установить размеры окна просмотра в режиме landscape с помощью isLandscape boolean.
Ожидание загрузки страницы
Когда мы делаем скриншот, нужно убедиться, что страница загружена полностью. Можно указать, когда Puppeteer должен сделать скриншот с параметрами, переданными page.goto ().
await page.goto(
pageUrl,
{ waitUntil: 'networkidle2' }
);
Значение networkidle2 означает, что Puppeteer будет считать страницу полностью загруженной, если произошло не более двух сетевых подключений в течение не менее 500 мс.
Удаление фона
Нужно захватить только встраиваемые данные, отображаемые на странице, исключив из создаваемого скриншота белый фон. Это можно сделать, передав специальный параметр методу page.screenshot () .
await page.screenshot({
omitBackground: true
});
Пожалуйста, оставьте ваши мнения по текущей теме статьи. Мы очень благодарим вас за ваши комментарии, отклики, дизлайки, подписки, лайки!