Создание скриншотов страницы

Puppeteer — это мощная библиотека для автоматизации браузера, которая позволяет взаимодействовать с веб-страницами в режиме headless (без графического интерфейса) или с полным интерфейсом. Один из типичных сценариев использования Puppeteer — это создание скриншотов веб-страниц. В этой статье рассмотрим, как с помощью Puppeteer можно делать скриншоты, настраивать их параметры и использовать различные опции для получения нужного результата.

Основной функционал

Для создания скриншотов в Puppeteer используется метод page.screenshot(). Этот метод делает снимок всей страницы или её части и сохраняет его в файл, а также предоставляет различные параметры для кастомизации.

Пример базового использования:

const puppeteer = require(&

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('https://example.com');
  await page.screenshot({ path: 'example.png' });
  await browser.close();
})();

В данном примере создаётся браузер, открывается страница по указанному URL, и делается скриншот всей страницы. Снимок сохраняется в файл с именем example.png.

Основные параметры метода screenshot

Метод page.screenshot() имеет несколько полезных опций, которые позволяют настроить внешний вид и поведение скриншота.

  1. path — указывает путь для сохранения файла. Если путь не указан, изображение будет возвращено как буфер данных.
  2. fullPage — если установлен в true, будет сделан скриншот всей страницы (включая область, видимую на экране и те части, которые скрыты за пределами экрана). По умолчанию false.
  3. clip — позволяет сделать скриншот определенной области страницы. Это объект с полями x, y, width и height, указывающими координаты и размеры прямоугольной области для снимка.
  4. quality — используется только для формата jpeg и определяет качество изображения от 0 до 100. По умолчанию 92.
  5. type — формат изображения. Может быть png или jpeg. По умолчанию используется png.
  6. omitBackground — если установлено в true, фон страницы будет прозрачен. Работает только с форматом png.

Пример с параметрами:

await page.screenshot({
  path: 'example-fullpage.png',
  fullPage: true,
  type: 'png',
  quality: 80
});

Создание скриншотов определённых областей

Иногда требуется сделать скриншот не всей страницы, а только её части. Для этого используется параметр clip. В объекте clip нужно указать координаты начала области (x, y) и размеры области (width, height).

Пример создания скриншота части страницы:

await page.screenshot({
  path: 'example-clip.png',
  clip: {
    x: 0,
    y: 0,
    width: 500,
    height: 500
  }
});

Этот код сделает снимок области с верхним левым углом в точке (0, 0) и размерами 500x500 пикселей.

Ожидание полной загрузки страницы

При работе с динамическими веб-страницами, особенно с современными SPA (Single Page Application), скриншот может быть сделан до того, как страница полностью загрузится или отрисуется. Чтобы избежать ошибок, важно дождаться полной загрузки страницы перед выполнением скриншота.

Пример с ожиданием загрузки:

await page.goto('https://example.com', { waitUntil: 'networkidle2' });
await page.screenshot({ path: 'example-loaded.png' });

Опция waitUntil: ‘networkidle2’ указывает Puppeteer ожидать, пока не завершится вся сетевая активность на странице (когда за 500 мс не будет происходить запросов).

Сохранение скриншотов в буфер

Метод page.screenshot() может вернуть данные скриншота как буфер, который можно использовать в других частях программы, например, отправить по сети или вставить в базу данных. Для этого достаточно не указывать параметр path.

Пример получения скриншота в виде буфера:

const screenshotBuffer = await page.screenshot();

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

Работа с несколькими скриншотами

В некоторых случаях необходимо сделать несколько скриншотов различных частей страницы или нескольких страниц. Для этого можно использовать асинхронные вызовы в цикле.

Пример создания нескольких скриншотов:

const urls = ['https://example1.com', 'https://example2.com'];

for (let i = 0; i < urls.length; i++) {
  const page = await browser.newPage();
  await page.goto(urls[i]);
  await page.screenshot({ path: `screenshot-${i + 1}.png` });
  await page.close();
}

Тестирование и сравнение скриншотов

Puppeteer часто используется в тестировании веб-приложений. В таких случаях важно уметь сравнивать скриншоты для выявления визуальных изменений. Для этого можно сохранить эталонные скриншоты и в дальнейшем сравнивать их с новыми.

Для сравнения изображений существует множество библиотек, таких как pixelmatch, которая позволяет находить различия между двумя изображениями.

Пример сравнения двух скриншотов:

const pixelmatch = require('pixelmatch');
const fs = require('fs');
const { PNG } = require('pngjs');

const img1 = PNG.sync.read(fs.readFileSync('baseline.png'));
const img2 = PNG.sync.read(fs.readFileSync('new.png'));

const diff = new PNG({ width: img1.width, height: img1.height });
const numDiffPixels = pixelmatch(img1.data, img2.data, diff.data, img1.width, img1.height, { threshold: 0.1 });

fs.writeFileSync('diff.png', PNG.sync.write(diff));

console.log(`${numDiffPixels} пикселей отличаются.`);

Этот пример использует библиотеку pixelmatch для сравнения двух изображений и создания изображения с различиями.

Заключение

Создание скриншотов с помощью Puppeteer предоставляет разработчикам мощный инструмент для визуального тестирования и анализа веб-страниц. С помощью простых настроек можно легко получать снимки экрана, адаптированные под конкретные задачи. Важно помнить о возможности настройки области скриншота, формате сохранения и других параметрах, которые могут существенно упростить работу с Puppeteer в тестировании и автоматизации.