Парсинг и скрапинг данных на TypeScript: почему это ваш новый супер-инструмент
Вы когда-нибудь мечтали собрать ценные данные с десятков сайтов за минуты, а не недели? Или автоматизировать рутинный сбор информации для своего образовательного проекта? Если да, то вы попали по адресу. Сегодня мы поговорим о том, как парсинг на TypeScript может превратить вас в настоящего повелителя данных.
Многие думают, что парсинг — это удел Python. Да, Python — король прототипов, но когда проект становится серьёзным, на сцену выходит TypeScript. Строгая типизация, удобная работа с асинхронностью и отличная поддержка IDE делают скрапинг данных на TypeScript не просто возможным, а чертовски приятным занятием. Давайте разбираться, как это работает.
Почему TypeScript, а не только Python для парсинга?
Прежде чем нырять в код, давайте честно признаем: Python прекрасен для быстрого старта. Но у TypeScript есть свои козыри:
- Типизация спасает от глупых ошибок. Вы точно знаете, что возвращает функция — строку, массив или объект. Никаких неожиданных
undefinedв рантайме. - Асинхронность из коробки.
async/awaitв TypeScript работает идеально, а это критично для парсинга, где нужно одновременно обрабатывать сотни запросов. - Экосистема Node.js. Все лучшие библиотеки для парсинга (Cheerio, Puppeteer, Playwright) имеют отличные типы для TypeScript.
- Масштабируемость. Код на TypeScript легче поддерживать в больших проектах, особенно если вы пишете парсер для целого курса или образовательной платформы.
Если вы разработчик, который хочет писать чистый, понятный и надёжный код — парсинг на TypeScript станет вашим любимым инструментом.
Библиотеки для парсинга: выбираем оружие
В мире TypeScript есть три главных героя. У каждого своя суперсила:
1. Cheerio — лёгкая артиллерия
Если вам нужно просто распарсить HTML и извлечь данные, не загружая весь браузер — Cheerio ваш выбор. Он работает как jQuery на сервере, но без визуального рендеринга. Идеален для статических страниц.
2. Puppeteer — тяжёлая артиллерия
Когда сайт использует JavaScript для отрисовки контента (React, Angular, Vue), Cheerio бессилен. Тут в игру вступает Puppeteer — он управляет настоящим браузером Chrome. Можно кликать, скроллить, ждать появления элементов.
3. Playwright — современный универсал
Эволюция Puppeteer от Microsoft. Поддерживает Chrome, Firefox, Safari. Более стабилен и быстр. Если начинаете новый проект — присмотритесь к Playwright.
Для нашего урока мы будем использовать Cheerio (для простоты) и Puppeteer (для сложных сценариев). Поехали!
Практика: пишем первый парсер на TypeScript
Представим, что мы хотим собрать список всех статей с блога (например, pythonlib.ru). Создадим простой, но рабочий скрапер.
Шаг 1. Установка и настройка проекта
Создаём папку и инициализируем проект:
mkdir typescript-parser
cd typescript-parser
npm init -y
npm install cheerio axios typescript @types/node --save-dev
npx tsc --init
Настраиваем tsconfig.json: включаем "module": "commonjs" и "target": "ES2020".
Шаг 2. Пишем код парсера
Создадим файл parser.ts:
import axios from 'axios';
import * as cheerio from 'cheerio';
interface Article {
title: string;
link: string;
date: string;
}
async function parseArticles(url: string): Promise<Article[]> {
try {
const response = await axios.get(url);
const html = response.data;
const $ = cheerio.load(html);
const articles: Article[] = [];
// Допустим, статьи лежат в элементах .post-item
$('.post-item').each((index, element) => {
const title = $(element).find('.post-title a').text().trim();
const link = $(element).find('.post-title a').attr('href') || '';
const date = $(element).find('.post-date').text().trim();
if (title) {
articles.push({ title, link, date });
}
});
return articles;
} catch (error) {
console.error('Ошибка парсинга:', error);
return [];
}
}
// Запускаем
const blogUrl = 'https://pythonlib.ru/blog';
parseArticles(blogUrl).then(articles => {
console.log(`Найдено ${articles.length} статей:`);
articles.forEach(a => console.log(`- ${a.title} (${a.date})`));
});
Обратите внимание на интерфейс Article — это и есть магия TypeScript. Мы чётко описали структуру данных, и IDE будет подсвечивать ошибки, если вы случайно обратитесь к несуществующему полю.
Шаг 3. Запускаем и проверяем
Компилируем и запускаем:
npx tsc
node parser.js
Если всё сделано правильно, вы увидите список статей в консоли. Просто, правда?
Парсинг динамических сайтов с Puppeteer
Теперь усложним задачу. Представьте, что сайт загружает контент через API после прокрутки страницы. Cheerio тут не поможет — нужен Puppeteer.
Устанавливаем:
npm install puppeteer
Пишем скрипт для сбора данных с бесконечной лентой:
import puppeteer from 'puppeteer';
async function scrapeDynamicPage(url: string) {
const browser = await puppeteer.launch({ headless: true });
const page = await browser.newPage();
await page.goto(url, { waitUntil: 'networkidle2' });
// Ждём появления контента
await page.waitForSelector('.content-item');
// Скроллим вниз, чтобы подгрузить ещё элементы
for (let i = 0; i < 3; i++) {
await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight));
await page.waitForTimeout(2000); // ждём загрузки
}
// Извлекаем данные
const items = await page.evaluate(() => {
const elements = document.querySelectorAll('.content-item');
return Array.from(elements).map(el => ({
title: el.querySelector('.title')?.textContent?.trim() || '',
description: el.querySelector('.desc')?.textContent?.trim() || '',
}));
});
console.log('Собрано элементов:', items.length);
await browser.close();
return items;
}
// Используем
scrapeDynamicPage('https://example.com/dynamic-content');
Этот код показывает, как скра