Для работы с Puppeteer в среде JavaScript необходим Node.js версии не ниже 14. Установка осуществляется через npm:
npm install puppeteer
Импортировать библиотеку можно стандартным образом:
const puppeteer = require(&
Создание браузера и страницы выполняется с помощью методов
puppeteer.launch() и browser.newPage(). Пример
инициализации:
(async () => {
const browser = await puppeteer.launch({ headless: true });
const page = await browser.newPage();
await page.goto('https://example.com');
await browser.close();
})();
Параметр headless контролирует видимость браузера:
true запускает его в фоне, false — отображает
окно для отладки.
Основы кластеризации
Кластеризация в контексте Puppeteer позволяет параллельно
выполнять множество задач в отдельных экземплярах браузера или
страниц. Это критично для ускорения тестирования и
веб-скрейпинга больших объёмов данных, особенно если страницы нагружены
JavaScript.
В отличие от последовательного выполнения, кластеризация использует
pool ресурсов, где несколько воркеров обрабатывают
задачи одновременно, снижая время ожидания сетевых запросов и
рендеринга.
Использование библиотеки puppeteer-cluster
Для удобного управления кластерами применяется пакет
puppeteer-cluster:
npm install puppeteer-cluster
Импорт и создание кластера:
const { Cluster } = require('puppeteer-cluster');
(async () => {
const cluster = await Cluster.launch({
concurrency: Cluster.CONCURRENCY_PAGE,
maxConcurrency: 4,
puppeteerOptions: { headless: true }
});
await cluster.task(async ({ page, data: url }) => {
await page.goto(url);
const title = await page.title();
console.log(`Title of ${url} is ${title}`);
});
cluster.queue('https://example.com');
cluster.queue('https://example.org');
await cluster.idle();
await cluster.close();
})();
Ключевые моменты:
-
concurrency определяет тип параллелизма. Доступны:
-
Cluster.CONCURRENCY_PAGE — отдельная страница на воркера.
-
Cluster.CONCURRENCY_CONTEXT — отдельный браузерный
контекст, полезно для изоляции сессий.
-
Cluster.CONCURRENCY_BROWSER — отдельный браузер на воркера,
максимум изоляции, но высокая нагрузка на память.
-
maxConcurrency — количество параллельных воркеров.
Оптимальное значение зависит от ресурсов машины и сложности страниц.
Обработка ошибок и повторные попытки
Кластеры Puppeteer позволяют автоматически обрабатывать ошибки:
cluster.on('taskerror', (err, data, willRetry) => {
if (willRetry) {
console.warn(`Ошибка на ${data}. Повторная попытка...`);
} else {
console.error(`Ошибка на ${data}: ${err.message}`);
}
});
Опция retryLimit задает количество повторов:
const cluster = await Cluster.launch({
concurrency: Cluster.CONCURRENCY_PAGE,
maxConcurrency: 4,
puppeteerOptions: { headless: true },
retryLimit: 3
});
Масштабирование задач
Кластеризация особенно полезна при скрейпинге сотен и тысяч страниц.
Очередь задач строится динамически:
const urls = ['https://site1.com', 'https://site2.com', 'https://site3.com'];
urls.forEach(url => cluster.queue(url));
Каждый воркер выполняет задачу независимо. Можно передавать в
cluster.queue не только строки, но и сложные объекты с
данными для теста:
cluster.queue({ url: 'https://example.com', selector: '.item' });
Внутри task можно обращаться к этим данным:
await page.waitForSelector(data.selector);
const text = await page.$eval(data.selector, el => el.textContent);
Оптимизация ресурсов
При больших объёмах данных важно контролировать потребление памяти и
CPU:
-
Headless режим снижает нагрузку на графическую
подсистему.
-
Использование контекстов вместо отдельных браузеров
экономит ресурсы, если изоляция сессий не критична.
-
Регулировка maxConcurrency предотвращает падение
системы из-за перегрузки.
-
Закрытие ненужных страниц:
await page.close();
Примеры комплексного использования
- Скрейпинг с сохранением результатов
const fs = require('fs');
const results = [];
await cluster.task(async ({ page, data: url }) => { await
page.goto(url); const title = await page.title(); results.push({ url,
title }); });
urls.forEach(url => cluster.queue(url));
await cluster.idle(); await cluster.close();
fs.writeFileSync('results.json', JSON.stringify(results, null,
2));
- Параллельное тестирование UI
Кластеризация позволяет одновременно проверять несколько сценариев:
const tests = [ { url: 'https://example.com/login', action:
'login' }, { url: 'https://example.com/signup', action: 'signup'
}];
await cluster.task(async ({ page, data }) => { await
page.goto(data.url); if (data.action === 'login') { await
page.type('#user', 'admin'); await page.type('#pass', '123'); await
page.click('#submit'); } else if (data.action === 'signup') { await
page.type('#email', 'test@example.com'); await page.click('#register');
} });
tests.forEach(test => cluster.queue(test));
Выводы по кластеризации
-
Ускоряет тестирование и скрейпинг, используя
параллельные воркеры.
-
Позволяет изолировать сессии и страницы, что критично
для сложных UI-тестов.
-
Облегчает обработку ошибок и повторов через встроенные
механизмы
puppeteer-cluster.
-
Гибко масштабируется под ресурсы машины с помощью
параметров
maxConcurrency и concurrency.
Кластеризация — базовый инструмент для любого серьезного проекта на
Puppeteer, где важны скорость, надежность и
масштабируемость параллельных задач.