Делайте лучшие скриншоты с Puppeteer
Изображения - важная часть каждого веб-сайта. Они помогают передать смысл и эмоции, и они могут сделать любой дизайн более привлекательным - или менее, в зависимости от того, как вы их используете. Итак, будь то фотографии, иллюстрации или рендеры, получение хороших изображений - важный шаг в веб-разработке.
Использование снимков экрана - обычная практика, особенно для веб-разработчиков, демонстрирующих свои работы в портфолио; но самые популярные инструменты для захвата экрана не допускают большой настройки, поэтому качество получаемых изображений может быть недостаточно хорошим. К счастью, есть и другие инструменты; как Puppeteer, который допускает множество настроек.
Что такое Puppeteer?
Puppeteer - это библиотека Node, которая предоставляет высокоуровневый API для управления Chrome или Chromium по протоколу DevTools. По умолчанию Puppeteer работает в headless режиме, но его можно настроить для запуска полного (non-headless) Chrome или Chromium.
Когда вы устанавливаете Puppeteer, он загружает последнюю версию Chromium (~170 МБ для Mac, ~282 МБ для Linux, ~280 МБ для Win), которая гарантированно работает с API.
С помощью Puppeteer вы можете автоматизировать многие задачи, одна из которых - создание снимков экрана.
Приступим
Для начала вам необходимо установить Puppeteer:
npm install puppeteer
или
yarn add puppeteer
Затем создайте файл со следующим кодом:
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://www.w3schools.com/howto/tryhow_css_example_website.htm');
await page.screenshot({ path: 'example.png' });
await browser.close();
})();
Приведенный выше код делает снимок экрана w3schools.com/howto/tryhow_css_example_webs.. и сохраняет его в example.png.
Разрешение
По умолчанию скриншоты имеют размер 800x600 пикселей, но вы можете изменить их разрешение:
await page.setViewport({
width: 640,
height: 480,
deviceScaleFactor: 1
});
setViewport
изменяет размер страницы, поэтому, если страница, снимок экрана которой вы хотите сделать, плохо обрабатывает изменение размера области просмотра, вы можете вызвать этот метод перед вызовом goto
.
Изменение deviceScaleFactor
позволяет получить изображение с другим разрешением без изменения размера области просмотра. Это может быть полезно, если вам нужно изображение с высоким разрешением с макетом страницы, специфичным для определенного размера области просмотра.
Ожидание загрузки элементов
Возможно, что некоторые элементы не полностью загружены при создании снимка экрана. Вы можете заставить свой скрипт ждать, пока они загрузятся, используя два разных метода:
await page.waitForSelector('img');
await page.waitForXPath('//img');
Оба метода вернутся, как только появится указанный селектор или XPath, поэтому они будут ждать только загрузки первого элемента с указанным селектором или XPath.
Жду еще немного
Вы также можете заставить свой скрипт ждать несколько миллисекунд:
await page.waitForTimeout(1000);
Это может быть полезно, чтобы заставить ваш скрипт дождаться завершения анимации перед тем, как сделать снимок экрана (или заставить ваш скрипт ждать загрузки элементов, если вы чувствуете себя ленивым и не хотите получать селектор или XPath элементов).
Обычно рекомендуется не ждать несколько секунд, а вместо этого использовать Page.waitForSelector(), Page.waitForXPath() или Page.waitForFunction(), чтобы дождаться именно тех условий, которые вы хотите.
Полный скриншот страницы
Вы можете делать скриншоты полного прокручивать страницу, задав fullPage
как true
:
await page.screenshot({ path: 'example.png', fullPage: true });
Определенная область страницы
Вы можете делать снимки экрана определенной области страницы, установив объект clip
с координатами x
и y
левого верхнего угла области, а также шириной и высотой области:
await page.screenshot({
clip: {
x: 50,
y: 100,
width: 150,
height: 100
},
});
Прозрачность
Вы можете делать скриншоты без белого фона с установкой omitBackground
на true
:
await page.screenshot({ path: 'example.png', omitBackground: true });
Имейте в виду, что это применимо только к фону по умолчанию, поэтому, если фон любого элемента непрозрачен, он будет отображаться на снимке экрана. Не волнуйтесь, вы можете сделать фон любого элемента прозрачным, запустив JavaScript в контексте страницы.
Запуск JavaScript
Вы можете запустить функцию JavaScript в контексте страницы:
await page.evaluate(() => {
let element = document.getElementById('elementWithBackground');
element.style.background = 'transparent';
document.body.style.background = 'transparent';
});
Приведенный выше код устанавливает прозрачность фона элемента с идентификатором elementWithBackground и тела, но вы можете изменить страницу любым способом, чтобы получить точный снимок экрана, который вам нужен.
Обратите внимание на размер
Частью улучшения взаимодействия с пользователем является обеспечение того, чтобы конечный пользователь мог видеть изображения, а этого не произойдет, если они используют телефон 3G при попытке загрузить изображение размером 42 МБ. Убедитесь, что изображения, которые вы отправляете конечному пользователю, подходящего размера!
Заключение
Этот пост должен помочь вам получить большинство необходимых вам снимков экрана, но вы всегда можете взглянуть на документацию Puppeteer, чтобы узнать больше.
Вот код с большинством методов, упомянутых в этом посте:
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.setViewport({
width: 640,
height: 480,
deviceScaleFactor: 1
});
await page.goto('https://www.w3schools.com/howto/tryhow_css_example_website.htm');
await page.waitForSelector('img');
await page.waitForTimeout(1000);
await page.evaluate(() => {
let element = document.getElementById('elementWithBackground');
element.style.background = 'transparent';
document.body.style.background = 'transparent';
});
await page.screenshot({ path: 'example.png', fullPage: true, omitBackground: true });
await browser.close();
})();