Зачем парсить данные на JavaScript, если есть Python?
Привет, друг! Если ты читаешь этот текст, то, скорее всего, уже знаком с Python и его библиотеками вроде BeautifulSoup или Scrapy. Но вдруг ты столкнулся с задачей, где Python пасует? Например, нужно собрать данные с сайта, который полностью построен на React или Angular. Вся информация подгружается через JavaScript, а в исходном HTML — пустота. Вот тут на сцену выходит JavaScript!
Парсинг и скрапинг данных на JavaScript — это не просто модный тренд, а насущная необходимость для работы с современными веб-приложениями. Node.js позволяет запускать браузерный движок прямо на сервере, обрабатывать DOM, кликать по кнопкам и ждать загрузки асинхронного контента. В этой статье мы разберем реальные инструменты и напишем код, который можно сразу использовать в ваших проектах.
Готовы превратить JavaScript в мощный пылесос для данных? Поехали!
Основные инструменты для скрапинга на JavaScript
Прежде чем писать код, давайте познакомимся с главными «бойцами» нашего арсенала. Для парсинга данных на JavaScript мы будем использовать три кита:
- Axios — HTTP-клиент для отправки запросов и получения HTML-кода страниц.
- Cheerio — быстрая и легковесная библиотека для парсинга HTML, которая работает как jQuery на сервере.
- Puppeteer — полноценный headless-браузер (Chrome), который умеет выполнять JavaScript, кликать, скроллить и ждать.
Для статических страниц вам хватит Axios + Cheerio. Если сайт подгружает данные через AJAX или требует авторизации — берите Puppeteer. А теперь перейдем к практике.
Пример 1: Простой парсинг статической страницы с Cheerio
Допустим, нам нужно собрать заголовки новостей с сайта, который отдает HTML сразу (без динамики). Устанавливаем зависимости:
npm install axios cheerio
Теперь напишем скрипт, который вытащит все заголовки h2 с главной страницы (замените URL на реальный):
const axios = require('axios');
const cheerio = require('cheerio');
async function parseStaticPage(url) {
try {
const { data } = await axios.get(url);
const $ = cheerio.load(data);
const titles = [];
$('h2').each((i, el) => {
titles.push($(el).text().trim());
});
console.log('Найденные заголовки:');
titles.forEach((title, index) => {
console.log(`${index + 1}. ${title}`);
});
} catch (error) {
console.error('Ошибка парсинга:', error.message);
}
}
parseStaticPage('https://example.com/news');
Этот код — база, с которой стоит начинать изучение скрапинга данных на JavaScript. Cheerio работает молниеносно, но не умеет выполнять скрипты. Если сайт показывает «Загрузка...» — читаем дальше.
Пример 2: Парсинг динамических страниц с Puppeteer
Теперь представим, что данные появляются только после того, как пользователь прокрутит страницу или нажмет кнопку «Показать еще». Для таких задач идеально подходит Puppeteer. Установим его:
npm install puppeteer
Сценарий: заходим на страницу с товарами, ждем 3 секунды (пока прогрузится JS), затем собираем названия товаров:
const puppeteer = require('puppeteer');
async function parseDynamicPage(url) {
const browser = await puppeteer.launch({ headless: true });
const page = await browser.newPage();
await page.goto(url, { waitUntil: 'networkidle2' });
// Ждем появления контента (селектор .product-title)
await page.waitForSelector('.product-title', { timeout: 10000 });
const items = await page.evaluate(() => {
const titles = [];
document.querySelectorAll('.product-title').forEach(el => {
titles.push(el.textContent.trim());
});
return titles;
});
console.log('Товары на странице:', items);
await browser.close();
}
parseDynamicPage('https://shop.example.com/catalog');
Обратите внимание на waitUntil: 'networkidle2' — это заставляет Puppeteer ждать, пока все сетевые запросы завершатся. Без этого вы рискуете получить пустой список. Парсинг JavaScript-страниц требует терпения, но Puppeteer дает полный контроль над браузером.
Как обходить блокировки и капчи?
Реальные сайты не любят, когда их парсят. Вот несколько приемов, которые помогут вашему веб-скрапингу на Node.js оставаться незаметным:
- User-Agent — всегда подставляйте заголовок реального браузера. В Axios это делается так:
headers: { 'User-Agent': 'Mozilla/5.0...' }. - Прокси — используйте ротацию IP-адресов. Например, сервисы Bright Data или ScrapingBee.
- Задержки — не долбите сервер запросами каждую миллисекунду. Добавьте
await page.waitForTimeout(2000)между действиями. - Капча — для обхода используйте сервисы распознавания (2Captcha) или эмулируйте человеческое поведение (движение мыши, случайные паузы).
Пример настройки User-Agent в Puppeteer:
await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36...');
await page.setExtraHTTPHeaders({
'Accept-Language': 'en-US,en;q=0.9',
});
Помните: этичный парсинг — это когда вы не перегружаете сервер и соблюдаете robots.txt. Всегда проверяйте юридическую сторону вопроса!
Сбор данных с API: элегантный подход
Иногда проще не парсить HTML, а найти скрытое API. Многие сайты подгружают данные через JSON-запросы. Как это обнаружить? Откройте вкладку Network в инструментах разработчика браузера и ищите XHR-запросы с ответами в формате JSON.
Пример: сайт интернет-магазина отправляет запрос на /api/products?page=1. Мы можем имитировать этот запрос через Axios и получить чистые данные без парсинга DOM:
const axios = require('axios');
async function fetchFromAPI() {
const response = await axios.get('https://shop.example.com/api/products', {
params: { page: 1, limit: 50 },
headers: { 'X-Requested-With': 'XMLHttpRequest' }
});
console.log(response.data.products);
}
fetchFromAPI();
Этот метод быстрее и надежнее, чем парсинг HTML. Он идеален для автоматизации сбора данных с крупных платформ.
Сохранение результатов: JSON, CSV, база данных
Собра