INTEGRITY Документация

Puppeteer

Puppeteer ↗ одна из самых популярных библиотек, которая скрывает от разработчиков низкоуровневый протокол DevTools и предоставляет высокоуровневый API для удобной работы с Chrome/Chromium и автоматизации сессий браузера. Puppeteer используют для таких задач, как создание скриншотов, обход страниц и тестирование веб-приложений.

Обычно Puppeteer подключается к локальному браузеру Chrome или Chromium через порт DevTools. См. документацию Puppeteer API на Puppeteer.connect() метод ↗, где это описано подробнее.

Команда Workers создала форк версии Puppeteer и модифицировала её для подключения к API Workers Browser Run. После подключения разработчики могут использовать весь Puppeteer API ↗ как и при стандартной настройке.

Наша версия имеет открытый исходный код, её можно найти в форк Puppeteer от Cloudflare ↗. npm можно установить из npmjs ↗ как @cloudflare/puppeteer ↗:

npm i -D @cloudflare/puppeteer

Используйте Puppeteer в Worker

После того как привязка browser настроен и @cloudflare/puppeteer библиотека установлена, Puppeteer можно использовать в Worker:

import puppeteer from "@cloudflare/puppeteer";

export default {
	async fetch(request, env) {
		const browser = await puppeteer.launch(env.MYBROWSER);
		const page = await browser.newPage();
		await page.goto("https://example.com");
		const metrics = await page.metrics();
		await browser.close();
		return Response.json(metrics);
	},
};
import puppeteer from "@cloudflare/puppeteer";

interface Env {
	MYBROWSER: Fetcher;
}

export default {
	async fetch(request, env): Promise<Response> {
		const browser = await puppeteer.launch(env.MYBROWSER);
		const page = await browser.newPage();
		await page.goto("https://example.com");
		const metrics = await page.metrics();
		await browser.close();
		return Response.json(metrics);
	},
} satisfies ExportedHandler<Env>;

Этот скрипт запускает ↗ env.MYBROWSER браузер, открывает новая страница ↗, переходит на ↗ https://example.com/ ↗, получает загрузку страницы метрики ↗, закрывает ↗ браузер и выводит метрики в формате JSON.

Keep Alive

Если пользователи не указывают browser.close() то браузер останется открытым, готовым к повторному подключению, а также повторно используется но по умолчанию она автоматически закрывается через 1 минуту бездействия. Пользователи могут по желанию продлить время простоя до 10 минут с помощью keep_alive параметр, заданный в миллисекундах:

const browser = await puppeteer.launch(env.MYBROWSER, { keep_alive: 600000 });

При таком подходе браузер остаётся открытым до 10 минут, даже если он неактивен.

Задайте собственный User-Agent

Чтобы указать собственный user agent в Puppeteer, используйте page.setUserAgent() метод. Это полезно, если целевой сайт отдаёт разный контент в зависимости от user agent.

await page.setUserAgent(
	"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36",
);

Локальная отладка в headful-режиме (экспериментально)

При локальной разработке с wrangler dev или vite dev, Chrome по умолчанию запускается в режиме headless. Чтобы запустить Chrome в видимом режиме (headful), задайте X_BROWSER_HEADFUL переменную окружения:

X_BROWSER_HEADFUL=true npx wrangler dev

Или с помощью Cloudflare Vite plugin:

X_BROWSER_HEADFUL=true npx vite dev

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

Выбор элемента

Puppeteer предоставляет несколько способов выбора элементов на странице. CSS-селекторы работают как обычно, но XPath-селекторы не поддерживаются из-за ограничений безопасности среды выполнения Workers.

Вместо селекторов Xpath можно использовать селекторы CSS или page.evaluate() чтобы выполнять XPath-запросы в контексте браузера:

const innerHtml = await page.evaluate(() => {
	return (
		// @ts-ignore this runs on browser context
		new XPathEvaluator()
			.createExpression("/html/body/div/h1")
			// @ts-ignore this runs on browser context
			.evaluate(document, XPathResult.FIRST_ORDERED_NODE_TYPE).singleNodeValue
			.innerHTML
	);
});

Управление сессиями

Чтобы упростить управление сессиями браузера, мы добавили новые методы в puppeteer:

Список открытых сеансов

puppeteer.sessions() выводит список текущих выполняющихся сессий. Результат будет выглядеть примерно так:

[
	{
		"connectionId": "2a2246fa-e234-4dc1-8433-87e6cee80145",
		"connectionStartTime": 1711621704607,
		"sessionId": "478f4d7d-e943-40f6-a414-837d3736a1dc",
		"startTime": 1711621703708
	},
	{
		"sessionId": "565e05fb-4d2a-402b-869b-5b65b1381db7",
		"startTime": 1711621703808
	}
]

Обратите внимание, что сессия 478f4d7d-e943-40f6-a414-837d3736a1dc есть активное подключение Worker (connectionId=2a2246fa-e234-4dc1-8433-87e6cee80145), в то время как сеанс 565e05fb-4d2a-402b-869b-5b65b1381db7 бесплатен. Пока соединение активно, другие Worker не смогут подключиться к этой сессии.

Список последних сеансов

puppeteer.history() выводит список недавних сессий, как открытых, так и закрытых. Это удобно, чтобы оценить текущий объём использования.

[
	{
		"closeReason": 2,
		"closeReasonText": "BrowserIdle",
		"endTime": 1711621769485,
		"sessionId": "478f4d7d-e943-40f6-a414-837d3736a1dc",
		"startTime": 1711621703708
	},
	{
		"closeReason": 1,
		"closeReasonText": "NormalClosure",
		"endTime": 1711123501771,
		"sessionId": "2be00a21-9fb6-4bb2-9861-8cd48e40e771",
		"startTime": 1711123430918
	}
]

Сессия 2be00a21-9fb6-4bb2-9861-8cd48e40e771 была закрыта явным образом с помощью browser.close() клиентом, тогда как сессия 478f4d7d-e943-40f6-a414-837d3736a1dc была закрыта из-за достижения максимального времени простоя (см. ограничения).

Эту информацию можно также посмотреть в панели управления, хотя и с небольшой задержкой.

Действующие лимиты

puppeteer.limits() выводит ваши текущие лимиты:

{
	"activeSessions": [
		{ "id": "478f4d7d-e943-40f6-a414-837d3736a1dc" },
		{ "id": "565e05fb-4d2a-402b-869b-5b65b1381db7" }
	],
	"allowedBrowserAcquisitions": 1,
	"maxConcurrentSessions": 2,
	"timeUntilNextAllowedBrowserAcquisition": 0
}

Puppeteer API

Полный API Puppeteer можно найти в форк Puppeteer от Cloudflare ↗.