Когда речь заходит о примерах простейших парсеров страниц, то большинство готовых скриптов может поместиться на одной печатной странице. Откуда вообще берутся мега-программы с кучей библиотек и зависимостей? Как их можно так раздуть?
На самом деле всё достаточно просто: чем больше данных у вас появляется в работе, тем сложнее их обрабатывать и распределять, не менее тяжело отслеживать сбои и проблемы (для оперативного реагирования на инциденты).
Этот материал об инструментах для сбора данных, а также о построении сложных рабочих процессов обработки данных: как они проектируются, какие механики и архитектурные подходы применяются, как распределяются рабочие задачи, как они мониторятся и т.д. В общем, добро пожаловать в мега-мануал для разработчиков корпоративных парсеров.
Эффективная система сбора данных — это устойчивая, масштабируемая и максимально управляемая инфраструктура, способная извлекать структурированные данные из разнородных источников (сайтов, приложений, документов, скриншотов и т.п.) при минимальных рисках и высокой скорости обработки.
Но давайте детализируем. Что конкретно делает инструменты для сбора данных эффективными? Пройдёмся по обозначенным свойствам:
Это свойство оперативного изменения охвата: для работы с новым узлом или сайтом, типом содержимого и т.п. Если исходный скрипт будет слишком предметным, то его переделка может застопорить весь процесс веб-парсинга. Например, если вы писали анализатор комментариев для TikTok, но внезапно вам потребовалось собрать список тегов и оценки видео, то с большой вероятностью придётся создавать новые структуры данных и их свойств, добавлять поддержку таблиц и т.д. Всё это — кардинальная переделка. В этом случае ваш парсер имеет минимальную масштабируемость. Если бы вы изначально правильно спроектировали программу, то добавить обработку нового контента было бы проще простого. К масштабируемости можно также отнести возможность параллельной обработки сразу нескольких источников и потоков (data workflow): распределённые очереди, новые узлы, модули, внешние сервисы и т.п.
Это свойство, которое характеризует возможность работы парсера не смотря на наличие ошибок и иных ограничений, например, при срабатывании механизмов защиты целевого сайта (в виде капчи, банов или блокировок). Устойчивый парсер должен уметь из коробки обрабатывать типовые сбои: повторно обращаться к пропущенным страницам, сохранять прогресс (чтобы была возможность продолжить парсинг там, где вы закончили в прошлый раз, а не начинать всё с начала). Более сложные алгоритмы могут обрабатывать ошибки и пробовать применять альтернативные модули и механизмы обхода защиты, которые могут решить ту или иную проблему/ограничение.
Оператор софта для парсинга может не быть программистом. Но он должен иметь возможность влиять на работу программы, чтобы вовремя увидеть уведомление об ошибке или об отказе отдельного модуля, добавить новый список прокси (с ротацией или без), вручную решить капчу, указать особые свойства цифровых отпечатков (чтобы скрипт адаптировался под изменение политик целевого ресурса) и т.п.
Управляемость, это одновременно и гибкость: способность работать с разными форматами выгрузки данных, создание новых шаблонов для поиска структурированной информации, автоматическая очистка данных от мусора (тегов, спецсимволов и т.п.), установка своих чёрных списков (для исключения запрещённых адресов) и т.п.
Не менее интересны для управляемости возможность мониторинга и оценки рабочего процесса. Это свойство достигается за счёт внедрения метрик (в том числе со специальными дашбордами), логирования и отправки оперативных уведомлений (по наиболее востребованным и удобным каналам + можно подумать об интеграции сторонних бизнес-решений: CRM, бизнес-аналитика и т.п.).
В общем, если подвести итог, то правильный инструмент сбора данных должен иметь модульную структуру. Каждый модуль или подсистема должны отвечать за определённые функции и задачи. Только так вы сможете оперативно доработать/изменить систему, без её кардинальной переделки. Именно так инструмент сбора данных сможет стать по-настоящему эффективным.
Но тут стоит отметить, что вместе с повышением эффективности, растёт и сложность разработки: появляется необходимость создания интерфейсов управления, API, интеграций, конфигов и прочего. Примерно по этим причинам предметные инструменты сбора данных разрастаются до невероятных размеров.
Создание универсального парсера — это весьма сложный и трудоёмкий процесс. И при этом нет никакой гарантии, что созданный продукт будет на 100% решать любую предметную задачу. Чем больше задач способен решить один парсер, тем сложнее будет его интерфейс управления (речь об объёме параметров конфигурации).
Более логичный подход — создание собственного инструмента для сбора данных, который бы решал только те задачи, которые вам нужны. Такой парсер необязательно писать с нуля, можно использовать различные фреймворки и библиотеки.
Давайте расскажем об инструментах для сбора данных — какие они бывают и для чего применяются (какие предметные задачи решают).
Все инструменты сбора данных можно условно разделить на следующие группы:
Могут быть универсальными (c модульной структурой или без) или узкопрофильными, например, как парсеры email или сникер-боты. Чаще всего готовые программы имеют закрытый код и распространяются платно — это готовый коммерческий продукт со своей моделью монетизации.
Это облачная реализация парсеров, полностью готовая к эксплуатации. Ряд таких сервисов умеет решать только конкретные предметные задачи (они узкопрофильные), например, парсить только определённые целевые сайты и собирать с них фиксированный перечень данных.
Пример, таких веб-парсеров — Froxy Scraper (поддерживает операции мониторинга поисковой выдачи, сбора данных с маркетплейсов и пр.). А некоторые веб-сервисы позволяют создавать свои кастомные конфиги и потому способны парсить любые целевые сайты (в этом случае повышается порог входа).
Самая главная фишка — полный аутсорс всех технических операций. В облаке уже настроено всё необходимое, включая ротируемые прокси и многопоточность. На выходе вы получаете только структурированные данные (в удобном вам формате) и больше ничего лишнего.
Единственное неудобство, общение с такими веб-сервисами обычно ведётся по API (без графических интерфейсов). Хотя у некоторых представителей отрасли есть и GUI.
Это своего рода программные заготовки. Они имеют в своём составе все ключевые модули и продуманное ядро, но нуждаются в детальной настройке и адаптации под конкретный проект. Это как конструктор для программистов. Примеры фреймворков для парсинга — Scrapy. Фреймворки как правило распространяются бесплатно (с открытым исходным кодом), но без профильных знаний разобраться с их запуском практически невозможно.
Они нужны для точечной настройки парсера (фреймворка) или для реализации конкретных предметных задач. А так как задачи бываю разными, выделим основные направления отдельно (для понимания архитектуры инструментов сбора данных):
Впечатляет? В вашем парсере могут использоваться только некоторые или сразу все обозначенные инструменты.
А мы ещё не говорили об инструментах, которые облегчают процесс мониторинга и отвечают за обнаружение проблем.
Лучшие прокси-серверы для доступа к ценным данным со всего мира.
К наиболее вероятным метрикам, которые помогут с оценкой вашего процесса парсинга, можно отнести:
В качестве инструментов мониторинга и диагностики могут выступать: Prometheus + Grafana (визуализация), Sentry (централизованная обработка логов), Kibana + Elasticsearch (для индексации событий), Airflow / Prefect / Luigi (для оркестрации с оценкой успешности пайплайнов) и т.п.
Выбор языка программирования имеет решающее значение. И дело даже не в производительности или в особом синтаксисе, а в наличии готовых библиотек и фреймворков. Наиболее популярным языком для написания парсеров является Python, но у него есть и конкуренты.
Применение того или иного языка может зависеть от масштаба инструмента сбора данных, а также от архитектуры платформы рабочих процессов обработки данных. Не менее важны скорость разработки и личные предпочтения IT-команды (ведь заниматься сопровождением будут не посторонние люди и не собственник бизнеса).
Именно здесь самый богатый выбор предметных инструментов и библиотек:
Особо стоит отметить наличие фреймворка Scrapy, который представляет собой гибкий конструктор, легко интегрируемый с headless-браузерами, базами данных и другими инструментами. Под капотом есть всё необходимое для многопоточности и настройки своих правил парсинга. Интеграция с прокси реализуется с минимальными усилиями.
У нас есть отдельный материал по топовым библиотекам для веб-парсинга на Python.
JavaScript (и особенно Node.js) хорош для задач, когда нужно эмулировать работу пользователя в браузере, обрабатывать SPA и парсить сложные клиентские интерфейсы (в том числе с перестроением DOM-структур в реальном времени).
Node.js покажет себя максимально эффективно в случае написания высоконагруженных парсеров с масштабированием через бессерверные-фреймворки.
Если парсер будет работать на удалённом сервере, необязательно применять какой-то из языков программирования. Простейшие скрипты можно написать для командной строки, с использованием консольных утилит:
CLI-инструменты могут использоваться в том числе для запуска ваших парсеров из консоли, например, при разовом или периодическом использовании.
Создание устойчивого процесса сбора данных — это не только программирование парсеров. Эффективность, надёжность и масштабируемость системы зависят от сопутствующих компонентов: планирования задач, хранения данных, обработки ошибок, рассылки уведомлений и мониторинга в режиме реального времени.
Без этих компонентов любой парсер превращается в скрипт, написанный на коленке.
Планировщики автоматизируют регулярный запуск парсеров, позволяют строить цепочки задач и следить за их выполнением. С их помощью можно позаботиться о балансировке нагрузки и о других сопутствующих задачах.
Какие инструменты для планирования задач могут быть:
Выбор хранилища зависит от архитектуры инструмента сбора данных, объёма и характера самих данных. Наиболее востребованными инструментами можно назвать:
На самом деле обработку ошибок и продвинутый мониторинг системы с рассылкой оперативных уведомлений организовать сложнее всего. Ранее мы рассказывали о системе мониторинга инцидентов.
Ключевые инструменты и библиотеки для работы с логами и рассылкой уведомлений:
Без кода, только заготовка архитектуры. Предположим, что стоит задача регулярного парсинга новостей по списку целевых сайтов. Данные должны сохраняться в базу, а при наличии ошибок администратору должно отправляться уведомление в Slack.
Примерный стек компонентов:
Понимание масштаба и наиболее успешных архитектур приходит не сразу. Поэтому нет смысла начинать с изучения сложных инструментов сбора данных и пытаться построить свои процессы обработки данных на миллионы строк кода.
Лучше начать создание парсеров с азов: сначала простейшие скрипты «на коленке», потом усложнение с выгрузкой данных в таблицы и JSON, базы данных. Далее — обработка статусов и ошибок, распределение очередей и потоков, масштабирование.
Идеальной лучшей практики не существует, так что нет смысла стремиться разработать супер-инструмент.
Наш совет! Обкатайте минимальный жизнеспособный парсер на предметных задачах и сразу выявятся наиболее острые проблемы: какие механизмы защиты на целевом сайте (для каждого из них есть свои пути обхода), как выглядит код страницы и поиск нужных данных (от этого зависит набор библиотек для синтаксического анализа, в каких-то задачах не обойтись без ИИ), какая производительность при одном потоке.
И только после получения пилотных цифр и показателей можно задуматься о масштабировании.