Data & Analytics

Парсинг

Автоматический разбор данных из неудобного формата — HTML-страниц, логов, документов — в структурированный вид, пригодный для обработки.

Что такое парсинг

Парсинг (от англ. parsing — синтаксический разбор) — автоматическое извлечение данных из текста, у которого есть структура, но не та, которая нужна. На входе HTML-страница, лог, JSON или PDF; на выходе — строки таблицы с понятными полями.

В русском IT слово используется в двух смыслах, и их стоит различать:

  • Парсинг в узком смысле — разбор текста по грамматике. Этим занимается парсер компилятора, движок регулярных выражений, библиотека чтения JSON.
  • Парсинг в бытовом смысле — сбор данных с чужих сайтов, он же скрейпинг (web scraping). Именно это обычно имеют в виду, когда говорят «написать парсер». Дальше речь про него.

Как устроен парсер сайта

Очередь URL → HTTP-запрос (заголовки, cookies, прокси)
    ↓
Ответ: HTML / JSON / рендеринг JS в браузере
    ↓
Извлечение полей (CSS-селекторы, XPath)
    ↓
Нормализация: типы, даты, валюты, дедупликация
    ↓
Хранилище (БД, Parquet, очередь)

Первое, что стоит проверить перед написанием кода: нет ли у сайта API. Часто страница сама подтягивает данные XHR-запросом на внутренний JSON-эндпоинт — открыть DevTools, вкладку Network и посмотреть HAR быстрее, чем разбирать вёрстку. JSON стабилен, HTML переверстают через месяц.

Инструменты

Инструмент Когда брать
requests + BeautifulSoup Простые статические страницы, разовые задачи
lxml То же, но быстрее; XPath
Scrapy Полноценный краулер: очередь, конкурентность, пайплайны
Playwright, Selenium Контент рисуется JavaScript, нужен реальный браузер
pandas.read_html Готовые HTML-таблицы одной строкой
resp = requests.get(url, headers={"User-Agent": UA}, timeout=10)
resp.raise_for_status()

soup = BeautifulSoup(resp.text, "lxml")
for card in soup.select("div.product-card"):
    yield {
        "title": card.select_one("h3").get_text(strip=True),
        "price": int(card.select_one(".price")["data-value"]),
    }

Отдельно про регулярки: парсить ими HTML — классическая ошибка. Вложенные теги не описываются регулярным выражением в принципе, и такой парсер ломается на первом неожиданном пробеле. Для логов и плоских форматов они хороши, для разметки берите парсер дерева.

Что ломает парсеры

  • Рендеринг на JavaScript. В исходном HTML пусто, данные приезжают отдельным запросом. Либо найти этот запрос, либо поднимать браузер.
  • Смена вёрстки. Селектор div.col-3 > span:nth-child(2) умрёт при первом редизайне. Цепляйтесь за data-*-атрибуты и семантику, а не за позицию.
  • Блокировки. Rate limiting, HTTP-ошибки 403 и 429, капча, отпечаток браузера.
  • Пагинация. Обход постранично или скроллом; лимит выдачи часто обходится сужением фильтров.
  • Молчаливая порча данных. Сайт отдал 200 и страницу-заглушку — парсер бодро пишет пустые строки. Нужны проверки: если доля пустых полей выше порога, падать, а не продолжать.

Правила приличия и закона

Технически можно скачать почти всё; это не значит, что нужно. Практический минимум: уважать robots.txt и условия использования, не создавать нагрузку (задержка между запросами, ограничение конкурентности), не собирать персональные данные — в России их обработка регулируется 152-ФЗ, и «данные были в открытом доступе» законным основанием не является. Доступность страницы и право переопубликовать её содержимое — тоже разные вещи. А агрессивный парсер, кладущий чужой сайт запросами, по последствиям мало отличается от DDoS.

Инфраструктура

Парсинг упирается не в CPU, а в сеть: сотни соединений висят в ожидании ответа, процессор простаивает. Отсюда практика — асинхронные клиенты и десятки воркеров на скромной VPS; GPU здесь бесполезны. Исключение — Playwright и Selenium: каждый браузер съедает сотни мегабайт RAM, и память кончается раньше всего остального. Второй ресурс — IP-адреса: с одного адреса интенсивный обход блокируется быстро, поэтому в дело идут пулы прокси с ротацией. Результат складывают в БД или сырым слоем в object storage, а сам обход ставят на расписание — по сути это первая буква ETL.

Связанные термины

  • ETL / интеграция данных — куда парсинг встраивается как шаг Extract
  • Регулярные выражения — подходят для логов, но не для HTML
  • Прокси-сервер — ротация адресов при массовом обходе
  • API — почти всегда лучшая альтернатива разбору вёрстки
  • Python — язык, на котором пишут большинство парсеров
  • Big Data — что делают с данными, когда их набирается много

Готовы запустить GPU-задачу?

Запустить GPU-сервер