Puppeteer предоставляет высокоуровневый API для управления браузером Chromium, однако полная мощь инструмента раскрывается при прямом взаимодействии с Chrome DevTools Protocol (CDP). CDP — это низкоуровневый протокол, позволяющий отправлять команды и получать события от браузера, контролируя все аспекты его работы: сетевые запросы, DOM, производительность, инспекцию страниц и многое другое.
Для работы с CDP в Puppeteer используется метод
page.target().createCDPSession(). Он создаёт сессию для
текущей страницы, через которую можно напрямую посылать команды
протокола:
const puppeteer = require(&
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
const client = await page.target().createCDPSession();
await client.send('Network.enable');
await client.send('Page.enable');
})();
Важно: CDP-сессия привязана к конкретной вкладке или
целевому объекту (Target). Для управления всем браузером
создаётся сессия через browser._connection.
CDP предоставляет детальный контроль над сетевыми запросами. С помощью
команд Network можно перехватывать, блокировать или
модифицировать запросы:
await client.send('Network.setRequestInterception', {
patterns: [{ urlPattern: '*', resourceType: 'Document', interceptionStage: 'HeadersReceived' }]
});
client.on('Network.requestIntercepted', async (event) => {
const { interceptionId } = event;
await client.send('Network.continueInterceptedRequest', { interceptionId });
});
Ключевые моменты:
setRequestInterception позволяет указать паттерны URL, тип
ресурса и стадию перехвата.
continueInterceptedRequest разрешает или модифицирует
запрос, включая изменение заголовков и тела.
CDP даёт прямой доступ к DOM и JavaScript-окружению страницы. Команды
DOM и Runtime позволяют получать дерево
элементов, изменять их или выполнять код:
const { root: { nodeId } } = await client.send('DOM.getDocument');
const { nodeId: buttonId } = await client.send('DOM.querySelector', { nodeId, selector: 'button#submit' });
await client.send('DOM.setAttributeValue', {
nodeId: buttonId,
name: 'disabled',
value: 'true'
});
Для выполнения JavaScript на странице применяется
Runtime.evaluate:
const result = await client.send('Runtime.evaluate', {
expression: 'document.title'
});
console.log(result.result.value);
Особенности:
DOM работает с nodeId, который уникален для
каждой сессии.
CDP активно использует событийную модель. Каждая команда может
генерировать события, на которые можно подписаться через
client.on:
client.on('Network.responseReceived', (event) => {
console.log(`Ответ от ${event.response.url}: ${event.response.status}`);
});
client.on('Page.loadEventFired', () => {
console.log('Страница полностью загружена');
});
Советы:
waitForTimeout).
CDP открывает доступ к Performance и Profiler.
Например, можно измерить время загрузки страницы, CPU-профилирование и
использование памяти:
await client.send('Performance.enable');
const metrics = await client.send('Performance.getMetrics');
console.log(metrics.metrics);
Для CPU-профилирования используется Profiler.start и
Profiler.stop:
await client.send('Profiler.start');
await page.evaluate(() => {
for (let i = 0; i < 1e6; i++) Math.sqrt(i);
});
const profile = await client.send('Profiler.stop');
console.log(profile);
Прямая работа с CDP расширяет возможности Puppeteer, открывая доступ к низкоуровневым функциям браузера, которые недоступны через стандартные методы. Такой подход позволяет создавать точные, гибкие и производительные тесты, контролируя каждый аспект взаимодействия с веб-страницей.