Skip to content

scrape-helper

scrape-helper отвечает за автоматический сбор данных из внешних источников и публикацию raw-событий в транспортный контур.

Это не ETL “целиком”, а именно внешний collecting layer.

За что отвечает

  • cron-расписание и ручной запуск источников;
  • работа с внешними площадками;
  • parser lifecycle для каждого адаптера;
  • упаковка результата в CollectedRawRecord;
  • публикация source.raw.v1;
  • загрузка артефактов в MinIO/S3;
  • quarantine для проблемных элементов;
  • репортинг SourceRun статусов в backend;
  • runtime status и control API.

Поддерживаемые источники

КодЧто собираетОсновной артефактОсобенности
easuzзакупки ЕАСУЗRAW_HTMLHTML-список и карточки
eisзакупки ЕИСRAW_HTMLrelevance-фильтрация по атомному контуру
eis_contractsконтракты 44-ФЗRAW_HTMLотдельный поток договоров
eis_contracts_223договоры 223-ФЗRAW_HTMLотдельный поток 223-ФЗ
rnpРНПRAW_HTMLпоиск по нескольким режимам
fedresursриск-сигналы и банкротные сообщенияRAW_JSON или RAW_HTMLproduction-режим теперь через API
fnsпрофили компанийRAW_JSON и опциональный PDFможет скачивать выписку
gistorgiлоты ГИС ТоргиRAW_JSONAPI-like JSON source

Как устроен жизненный цикл

1. Инициализация

При старте сервис:

  1. читает env;
  2. резолвит ENABLED_SOURCES;
  3. создаёт список адаптеров;
  4. поднимает control API;
  5. планирует cron;
  6. подключается к RabbitMQ и MinIO.

2. Запуск адаптера

Каждый источник оформлен как SourceAdapter:

ts
export interface SourceAdapter {
  code: string;
  name: string;
  collect(context: SourceRunContext): Promise<CollectedRawRecord[]>;
}

Это позволяет добавлять и сопровождать новые источники без переписывания всего пайплайна.

3. Что возвращает адаптер

Адаптер возвращает не доменную сущность, а CollectedRawRecord.

Внутри обычно есть:

  • url
  • raw
  • metadata
  • artifacts

То есть парсер обязан сохранить максимум трассировки до первоисточника.

4. Публикация raw-событий

После collect() сервис:

  1. загружает артефакты в MinIO/S3;
  2. строит RawSourceEvent;
  3. валидирует его по contracts;
  4. публикует в RabbitMQ;
  5. при ошибке пытается отправить запись в quarantine queue.

5. Репортинг по SourceRun

До и после запуска scrape-helper отправляет в backend статусы:

  • RUNNING
  • SUCCESS
  • FAILED

Именно по ним UI потом показывает:

  • историю запусков;
  • health источников;
  • publication efficiency;
  • operational risk level.

Почему scrape-helper не должен писать в Postgres

Это архитектурно важная граница.

Если бы парсер писал доменные сущности напрямую:

  • любая смена HTML ломала бы бизнес-слой;
  • было бы труднее воспроизводить инциденты;
  • пропала бы граница между transport- и domain-level логикой;
  • UI и backend сильнее зависели бы от деталей площадки.

Control API

У сервиса есть лёгкий HTTP control-plane:

МетодURLНазначение
GET/healthhealth endpoint
POST/api/source-runsручной запуск источников
GET/api/runtime-configтекущее расписание
PUT/api/runtime-configобновление расписания и auto-run
GET/api/runtime-statusruntime status, loaded sources, circuit states

Пример ручного запуска:

bash
curl -X POST http://localhost:3001/api/source-runs \
  -H 'content-type: application/json' \
  -d '{"sourceCodes":["eis","fns"]}'

Важные env-переменные

Общие

  • RABBITMQ_URL
  • QUEUE_RAW_EVENT
  • QUEUE_QUARANTINE_EVENT
  • SCRAPE_SCHEDULE
  • REQUEST_TIMEOUT_MS
  • RETRY_ATTEMPTS
  • RETRY_BASE_DELAY_MS
  • CIRCUIT_BREAKER_FAILURE_THRESHOLD
  • CIRCUIT_BREAKER_OPEN_MS
  • S3_*
  • HTTP_PROXY
  • HTTPS_PROXY
  • NO_PROXY
  • ENABLED_SOURCES

Source-specific

  • EIS_*
  • EASUZ_*
  • RNP_*
  • FEDRESURS_*
  • FNS_*
  • GISTORGI_*

Что важно знать про внешние площадки

zakupki.gov.ru

Может:

  • отдавать нестабильный HTML;
  • требовать более “браузерный” профиль запроса;
  • резать автоматизированный трафик;
  • зависеть от правильного proxy-маршрута.

Fedresurs

Production-режим нужно строить на официальном API.

То есть для стабильного сбора понадобятся:

  • FEDRESURS_API_URL
  • FEDRESURS_API_LOGIN
  • FEDRESURS_API_PASSWORD

Ожидать, что старый HTML-список будет вечно надёжным, уже не стоит.

Когда менять именно этот репозиторий

Он нужен, если:

  • изменилась внешняя разметка площадки;
  • нужно увеличить глубину или лимиты сбора;
  • нужно расширить список поисковых запросов;
  • появился новый источник;
  • нужно добавить новый артефакт;
  • SourceRun теперь должен репортить больше деталей.

Качество

bash
npm run check
npm run test
npm run build

Техническая и аналитическая документация платформы NPPWEB.