Веб-скрапинг и Puppeteer: Как легко отслеживать изменения на веб-страницах? Руководство по автоматизации работы с данными
Что такое веб-скрапинг и зачем он нужен?
Веб-скрапинг – это простой и удобный способ автоматически собирать данные с веб-страниц. Вместо того чтобы вручную копировать информацию, специальные программы делают это за вас, извлекая нужные данные из содержимого сайта. Веб-скрапинг экономит время, упрощает рутинные задачи и позволяет оставаться в курсе всех изменений в режиме реального времени.
Как работает веб-скрапинг?
- Программа заходит на сайт, как обычный пользователь;
- Она «читает» код страницы и находит нужные элементы – текст, изображения, ссылки или таблицы;
- Полученные данные сохраняются, чтобы их можно было анализировать или использовать дальше.
Это особенно полезно, когда информации много, она постоянно меняется или не представлена в удобном виде.
Почему важно отслеживать изменения на сайтах?
Интернет меняется каждую минуту, и следить за всем вручную очень сложно, да и не нужно, когда есть возможность использовать автоматизацию. Вот примеры того, зачем она нужна:
- Изменения цен
Представьте, вы ищете самые выгодные предложения в интернет-магазинах. Цены на товары могут меняться в зависимости от времени суток, сезона или активности конкурентов. Веб-скрапинг поможет быстро узнать, где самые низкие цены, или вовремя скорректировать стоимость своих товаров.
- Наличие товаров
Если вы хотите купить популярный товар, который часто бывает в дефиците, скрипт поможет вам отследить, когда он снова появится в продаже. Для бизнеса это полезно, чтобы понимать, что есть в наличии у поставщиков.
- Новости и обновления
Отслеживание свежих новостей, публикаций или изменений на важных страницах поможет всегда быть в курсе событий. Например, можно настроить сбор информации с новостных сайтов или блогов.
- Мониторинг конкурентов
Бизнесу важно знать, чем занимаются конкуренты: какие акции они проводят, что нового добавили в ассортимент, какие отзывы получают. Веб-скрапинг легко справляется с этой задачей.
Современные сайты часто загружают данные не сразу, а по мере действий пользователя – например, отзывы, рейтинги или статистику. Ручной сбор таких данных требует много времени, а автоматизация всё сделает за секунды.
Puppeteer: что это и зачем он нужен в веб-скрапинге?
Для сбора информации с сайтов нужны удобные и надёжные инструменты. Среди них отличается эффективностью и расширенным функционалом Puppeteer – библиотека для Node.js, которая позволяет имитировать действия реального пользователя: открывать страницы, кликать на элементы, заполнять формы и даже делать скриншоты – всё это в полностью автоматическом режиме.
Веб-скрапинг с Puppeteer становится гораздо проще, особенно когда речь идёт о динамических сайтах, где контент загружается с помощью JavaScript. Puppeteer не только «видит» то, что видит пользователь, но и позволяет взаимодействовать с этим контентом на более глубоком уровне, что делает его идеальным инструментом для сбора данных, тестирования сайтов и автоматизации задач любой сложности. Если вы работаете с JavaScript и TypeScript, Puppeteer станет отличным выбором для веб-скрапинга и многих других задач!
Преимущества Puppeteer
Ключевые преимущества, которые делают его таким популярным:
- Работа с динамическим контентом
Обычные инструменты для скрапинга (например, Axios, Cheerio) часто сталкиваются с трудностями при обработке сайтов, где контент загружается динамически с помощью JavaScript. Puppeteer же отлично справляется с этой задачей! Он запускает полноценный браузер (Google Chrome или Firefox), позволяя загружать страницы так же, как это делает настоящий пользователь. Это значит, что весь контент, даже тот, который появляется после выполнения скриптов, становится доступным для анализа и сбора данных.
- Манипуляции с элементами
Легко взаимодействовать с DOM – добавлять или убирать элементы, кликать на кнопки, заполнять формы, прокручивать страницы и многое другое.
- Headless-режим
Puppeteer позволяет управлять браузером как в обычном, так и в headless-режиме (без графического интерфейса).
Headless-режим — идеален для быстрой и незаметной автоматизации: браузер работает «в фоновом режиме», экономя ресурсы и ускоряя выполнение задач.
Полный режим браузера — полезен для отладки и разработки: можно визуально наблюдать за тем, что происходит на странице.
- Эмуляция устройства
Puppeteer также может имитировать устройства, меняя заголовок user-agent, что помогает обойти блокировки и ограничения сайтов. Можно даже симулировать сетевые режимы, такие как 3G или Wi-Fi, чтобы проверить производительность страницы.
- Скриншоты и создание PDF-документов
Можно делать снимки страниц или сохранять их в виде PDF-файлов. Это полезно для создания отчётов, документирования веб-контента или тестирования.
Все эти преимущества мы детально разберём в следующих разделах.
Таким образом, Puppeteer – это не просто инструмент для скрапинга, а универсальный помощник для любых задач, связанных с автоматизацией браузера. Давайте перейдём к установке Puppeteer и познакомимся с его возможностями на практике:
Установка Puppeteer
- Библиотека устанавливается очень легко. Для начала убедитесь, что у вас установлен Node.js (официальный сайт).
- Далее откройте терминал или командную строку и выполните npm команду:
npm i puppeteer
Эта команда автоматически скачивает последнюю версию Chromium. Если Chromium уже установлен или вы хотите использовать другой браузер, можно установить Puppeteer без него:
npm i puppeteer-core
Работа с DOM и пользовательскими действиями
Puppeteer предоставляет широкий спектр возможностей для автоматизации работы с веб-страницами. Он позволяет не только изменять содержимое страниц с помощью манипуляций с DOM (Document Object Model – структура веб-страницы, через которую можно управлять элементами и данными), но и имитировать действия пользователя. Давайте рассмотрим, как применить эти функции на практике.
Различные действия с DOM
Puppeteer позволяет:
- Добавлять или убирать элементы. Используйте методы evaluate(), чтобы выполнять JavaScript-код в контексте страницы.
await page.evaluate(() => {
const newElement = document.createElement('div');
newElement.textContent = 'Новый элемент!';
document.body.appendChild(newElement); // Добавляем элемент в DOM
});
- Изменять содержание страниц. Можно легко менять текст, атрибуты или стили элементов:
await page.evaluate(() => {
document.querySelector('h1').textContent = 'Обновлённый заголовок';
});
Имитирование пользовательских действий
Puppeteer может эмулировать действия пользователя, это особенно полезно для тестирования и скрапинга данных с интерактивных сайтов.
- Клики и прокрутка:
await page.click('button#submit'); // Клик по кнопке с id "submit"
await page.evaluate(() => window.scrollBy(0, 1000)); // Прокрутка вниз
- Ввод текста и заполнение форм:
await page.type('input[name="username"]', 'myUsername'); // Ввод текста в поле
await page.type('input[name="password"]', 'myPassword');
await page.click('button[type="submit"]'); // Отправка формы
- Автоматическая навигация. Puppeteer может переходить между страницами, отслеживать загрузку и взаимодействовать с новыми элементами:
await page.goto('https://example.com');
await page.waitForSelector('h1'); // Ждём появления заголовка
Работа с динамическими сайтами
Многие современные сайты используют JavaScript для загрузки контента асинхронно. Puppeteer легко справляется с такими задачами:
- Ожидание появления элементов, прежде чем взаимодействовать с ними:
await page.waitForSelector('.dynamic-element');
- Работа с асинхронно загружаемыми элементами. При скрапинге данных важно правильно обрабатывать элементы, которые появляются позже.
await page.waitForFunction(() => {
return document.querySelector('.loaded-content') !== null;
});
Параметры для веб-скрапинга с Puppeteer
Для эффективного и корректного веб-скрапинга с использованием Puppeteer необходимо учитывать различные параметры и настройки, которые помогут улучшить производительность, точность и стабильность процесса. Давайте рассмотрим ключевые параметры, которые можно использовать в проектах:
- Headless-режим. Puppeteer может работать в headless (без интерфейса) или headful (с интерфейсом) режиме.
const browser = await puppeteer.launch({ headless: true }); // По умолчанию true
- Настройка размеров окна и пользовательских агентов:
const browser = await puppeteer.launch({
args: ['--window-size=1920,1080']
});
const page = await browser.newPage();
await page.setViewport({ width: 1920, height: 1080 });
- Изменение User-Agent (помогает избежать блокировок и имитировать различные устройства):
await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36');
- Таймауты загрузки страницы:
await page.goto('https://example.com', { timeout: 60000 }); // Таймаут в 60 секунд
- Ожидание загрузки нужных элементов:
await page.waitForSelector('.dynamic-element', { visible: true });
- Ожидание навигации (полезно для отслеживания переходов между страницами):
await Promise.all([
page.waitForNavigation(),
page.click('a#next-page') // Клик и ожидание перехода
]);
- Отключение графических элементов (экономит ресурсы и ускоряет выполнение скрипта):
const browser = await puppeteer.launch({
args: ['--disable-gpu', '--no-sandbox']
});
- Эмуляция устройств:
const iPhone = puppeteer.devices['iPhone X'];
await page.emulate(iPhone);
- Использование прокси:
const browser = await puppeteer.launch({
args: ['--proxy-server=your-proxy-address']
});
- Управление куки и сессиями:
const cookies = [{ name: 'session', value: 'abc123', domain: 'example.com' }];
await page.setCookie(...cookies);
- Обход антибот-систем (Puppeteer-extra и плагины помогают обойти защиту от автоматизации):
npm install puppeteer-extra puppeteer-extra-plugin-stealth
const puppeteer = require('puppeteer-extra');
const stealthPlugin = require('puppeteer-extra-plugin-stealth');
puppeteer.use(stealthPlugin());
Параметры для сбора данных и мониторинга изменений:
- Получение текста и атрибутов элементов:
const title = await page.$eval('h1', element => element.textContent);
- Для отслеживания изменений используйте MutationObserver (встроенный в браузер объект JavaScript, который позволяет отслеживать изменения в DOM, такие как добавление или удаление элементов, изменение атрибутов или структуры документа, и реагировать на них):
await page.exposeFunction('onMutation', (mutations) => {
console.log('DOM изменился:', mutations);
});
await page.evaluate(() => {
const observer = new MutationObserver((mutations) => {
window.onMutation(mutations);
});
observer.observe(document.body, { childList: true, subtree: true });
});
Пример кода для веб-скрапинга
Теперь, применяя знания об основных параметрах Puppeteer, особенно в контексте веб-скрейпинга, давайте создадим простой пример кода, который продемонстрирует работу всех упомянутых возможностей на тестовом сайте Books to Scrape. Попробуем получить информацию о книгах:
const puppeteer = require('puppeteer');
(async () => {
// Запуск браузера с дополнительными параметрами для оптимизации и эмуляции
const browser = await puppeteer.launch({
headless: false, // Открытие браузера с интерфейсом
args: ['--no-sandbox'], // Дополнительные аргументы для повышения производительности
defaultViewport: { // Установка размера окна браузера
width: 1280,
height: 800
}
});
const page = await browser.newPage();
// Устанавливаем пользовательский агент (эмуляция браузера)
await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36');
// Переход на целевую страницу
await page.goto('https://books.toscrape.com/', { waitUntil: 'networkidle2' }); // Ожидание полной загрузки страницы
// Ожидание загрузки элементов на странице
await page.waitForSelector('ol.row li');
// Извлечение и вывод только названий книг
const bookTitles = await page.evaluate(() => {
const bookElements = document.querySelectorAll('ol.row li h3 a');
return Array.from(bookElements).map(book => book.getAttribute('title') || 'Название отсутствует');
});
// Вывод каждого названия с нумерацией списка
console.log('Названия книг:');
bookTitles.forEach((title, index) => console.log(`${index + 1}. ${title}`));
// Эмуляция клика на первую книгу для демонстрации пользовательских действий
await page.click('ol.row li h3 a');
await new Promise(resolve => setTimeout(resolve, 1000)); // Ожидание загрузки страницы книги
// Манипуляция DOM: изменение заголовка страницы
await page.evaluate(() => {
document.querySelector('h1').innerText = 'Заголовок изменён с помощью Puppeteer!';
});
// Создание скриншота страницы после изменения DOM
await page.screenshot({ path: 'book_page.png', fullPage: true });
// Генерация PDF-документа из текущей страницы
await page.pdf({ path: 'book_page.pdf', format: 'A4' });
// Наблюдение за изменениями на странице с использованием MutationObserver
await page.evaluate(() => {
const targetNode = document.body;
const observer = new MutationObserver((mutationsList) => {
for (let mutation of mutationsList) {
console.log('Обнаружено изменение:', mutation);
}
});
observer.observe(targetNode, { childList: true, subtree: true, attributes: true });
});
await browser.close();
})();
Отдельный код для отслеживания изменений на странице (например, обновление цен или доступности товаров) с использованием вышеупомянутого MutationObserver:
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({ headless: true });
const page = await browser.newPage();
await page.goto('https://books.toscrape.com/');
// Экспортируем функцию для передачи данных из браузера в Node.js
await page.exposeFunction('onMutation', (mutations) => {
mutations.forEach(mutation => {
console.log('Изменение:', mutation); // Логируем изменения
});
});
// Внедряем MutationObserver на страницу
await page.evaluate(() => {
const targetNode = document.querySelector('.row'); // Наблюдаем за контейнером со списком книг
const config = { childList: true, subtree: true, attributes: true }; // Настройки наблюдения
const observer = new MutationObserver((mutationsList) => {
window.onMutation(mutationsList.map(mutation => ({
type: mutation.type,
addedNodes: Array.from(mutation.addedNodes).map(node => node.outerHTML),
removedNodes: Array.from(mutation.removedNodes).map(node => node.outerHTML)
})));
});
observer.observe(targetNode, config);
});
// Имитируем взаимодействие для создания изменений (например, обновление страницы)
await page.click('li.next a'); // Переход на следующую страницу для демонстрации изменений
// Подождём, чтобы MutationObserver успел отловить изменения
await new Promise(resolve => setTimeout(resolve, 5000));
await browser.close();
})();
Разбор кода:
Expose Function. Метод page.exposeFunction() позволяет создать функцию onMutation(), которая будет передавать данные об изменениях из браузера в Node.js окружение.
MutationObserver. В page.evaluate() мы внедряем MutationObserver на странице. Он отслеживает изменения в указанном элементе (.row), где находятся книги.
config определяет, какие изменения отслеживать:
childList: добавление или удаление дочерних элементов.
subtree: наблюдение за всеми дочерними элементами.
attributes: изменения атрибутов элементов.
Действия при изменениях. При обнаружении изменений, данные передаются в функцию onMutation, и в консоль выводятся добавленные или удалённые элементы.
Дополнительные возможности
Обнаружение скрытых API сайтов
Многие веб-сайты используют внутренние API для загрузки данных динамически. Эти запросы часто скрыты от обычных пользователей, но Puppeteer помогает их обнаружить.
- Инструменты DevTools. Воспользуйтесь вкладкой Network в инструментах разработчика браузера, чтобы отследить запросы. Puppeteer может программно запускать DevTools-прокси:
await page.setRequestInterception(true);
page.on('request', request => {
console.log(request.url());
request.continue();
});
- Анализ XHR-запросов. Puppeteer фиксирует все XHR-запросы и позволяет легко увидеть, какие данные возвращаются.
Когда лучше использовать Puppeteer, а когда API?
Puppeteer: идеален для сложных сайтов, где требуется имитация пользовательских действий или обработка JavaScript-динамики.
API: лучше использовать для структурированных данных (например, JSON) и быстрой загрузки. Если сайт предоставляет официальный API — это более эффективный и законный способ сбора информации.
Настройка уведомлений при изменениях
Мониторинг с использованием Puppeteer можно дополнить уведомлениями, чтобы получать оповещения о важных изменениях:
- Использование WebSockets или Webhooks: отправка данных на сервер или мессенджер (например, Slack).
- Интеграция с почтой: отправка email при обнаружении изменений.
Пример мониторинга и уведомлений с использованием Puppeteer:
const puppeteer = require('puppeteer');
const nodemailer = require('nodemailer');
(async () => {
const browser = await puppeteer.launch({ headless: true });
const page = await browser.newPage();
await page.goto('https://example.com');
// Наблюдение за изменениями
const initialContent = await page.content();
setInterval(async () => {
const currentContent = await page.content();
if (currentContent !== initialContent) {
// Отправка уведомления
sendEmail('Изменение на сайте!', 'Контент был обновлен.');
}
}, 30000); // Проверка каждые 30 секунд
async function sendEmail(subject, text) {
let transporter = nodemailer.createTransport({ /* настройки SMTP */ });
await transporter.sendMail({ from: 'your_email', to: 'notify_email', subject, text });
}
await browser.close();
})();
Интеграция с CapMonster Cloud для решения CAPTCHA
Сайты часто используют капчи для защиты от автоматического сбора данных. Puppeteer позволяет интегрировать эффективный инструмент по автоматическому обходу различных типов капч CapMonster Cloud для их решения:
- Установка официальной библиотеки:
npm i @zennolab_com/capmonstercloud-client
- Пример извлечения динамических данных капчи от Amazon и её решения с помощью CapMonster Cloud:
const puppeteer = require('puppeteer');
const { CapMonsterCloudClientFactory, ClientOptions, AmazonProxylessRequest } = require('@zennolab_com/capmonstercloud-client');
(async () => {
const browser = await puppeteer.launch({ headless: false }); // Устанавливаем true для headless-режима
const page = await browser.newPage();
const pageUrl = 'https://example.com'; // URL страницы с капчей
await page.goto(pageUrl);
// Извлекаем параметры CAPTCHA с веб-страницы
const captchaParams = await page.evaluate(() => {
const gokuProps = window.gokuProps || {};
const scripts = Array.from(document.querySelectorAll('script'));
return {
websiteKey: gokuProps.key || "Not found",
context: gokuProps.context || "Not found",
iv: gokuProps.iv || "Not found",
challengeScriptUrl: scripts.find(script => script.src.includes('challenge.js'))?.src || "Not found",
captchaScriptUrl: scripts.find(script => script.src.includes('captcha.js'))?.src || "Not found"
};
});
console.log('Captcha Parameters:', captchaParams); // Проверяем извлеченные параметры
// Создаём задачу для отправки на сервер CapMonster Cloud
const cmcClient = CapMonsterCloudClientFactory.Create(new ClientOptions({
clientKey: 'your_api_key', // Замени на свой API-ключ CapMonster Cloud
}));
// Настройка запроса для решения капчи
const amazonProxylessRequest = new AmazonProxylessRequest({
websiteURL: pageUrl,
challengeScript: captchaParams.challengeScriptUrl,
captchaScript: captchaParams.captchaScriptUrl,
websiteKey: captchaParams.websiteKey,
context: captchaParams.context,
iv: captchaParams.iv,
cookieSolution: false,
});
// Решение CAPTCHA
const response = await cmcClient.Solve(amazonProxylessRequest);
if (!response?.solution) {
console.error('CAPTCHA не решена.');
await browser.close();
process.exit(1);
}
console.log('Captcha Solved:', response.solution);
await browser.close();
console.log('DONE');
process.exit(0);
})()
.catch(err => {
console.error(err);
process.exit(1);
});
Этика и юридические аспекты веб-скрапинга
Важно помнить об этических нормах и соблюдать установленные правила, чтобы веб-скрапинг был законным и безопасным. Ключевые принципы ответственного веб-скрапинга:
- Robots.txt: проверяйте директивы файла robots.txt, который определяет, какие страницы можно скрапить, а какие нельзя:
Allow: /public/
Disallow: /admin/
Disallow: /private/
Найти этот файл можно вручную через браузер (например: https://example.com/robots.txt) или используя Puppeteer:
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
// URL robots.txt файла
const robotsUrl = 'https://example.com/robots.txt';
await page.goto(robotsUrl);
// Получаем текст robots.txt
const robotsText = await page.evaluate(() => document.body.innerText);
console.log('Содержимое robots.txt:\n', robotsText);
await browser.close();
})();
- Необходимо ограничивать частоту запросов, чтобы не перегружать сервер. Используйте задержки между запросами (await page.waitForTimeout(3000);).
- Юридические аспекты:
Соблюдайте законы страны, убедитесь,, что скрапинг не нарушает местное законодательство.
Не публикуйте данные, защищённые авторским правом, без разрешения.
Некоторые сайты требуют явного разрешения на сбор данных.
Итак, мы разобрали основные функции Puppeteer для веб-скрапинга и теперь можем сделать вывод, что это эффективный способ автоматизировать сбор данных с веб-страниц, экономя время и предоставляя доступ к актуальной информации в реальном времени. Инструмент упрощает работу с динамическим контентом, эмуляцию действий пользователя и различные манипуляции с DOM.
В статье приведены примеры кода, демонстрирующие извлечение данных и работу с динамическим контентом. Эти примеры помогут вам быстрее освоить веб-скрапинг и адаптировать их под свои нужды.
Также интеграция с CapMonster Cloud является ключевым аспектом, который значительно повышает эффективность сбора данных, особенно когда сталкиваешься с веб-страницами, защищёнными различными видами капчи. Решение капчи часто становится препятствием для автоматизированных систем, затрудняя доступ к данным – в таких случаях CapMonster Cloud предоставляет возможность обходить эти защиты с высокой скоростью и точностью.
Puppeteer полезен для задач, требующих высокой точности, например, мониторинга цен или отслеживания новостей. Использование headless-режима и гибкой настройки помогает оптимизировать работу.
Puppeteer – это не только инструмент для скрапинга, но и универсальное решение для тестирования и различных задач по автоматизации. Надеемся, что этот обзор поможет вам в начале работы и вдохновит на создание собственных решений для автоматизации!
NB: Напоминаем, что продукт используется для автоматизации тестирования на ваших собственных сайтах и на сайтах, к которым у вас есть доступ на законных основаниях.