Парсер рубрик и организаций публичного зелёного справочника

Задача

Собрать структуру рубрик и полный список организаций публичного зелёного справочника по заданным городам — целиком, без ручной прокрутки каталога, без входа в аккаунт и без ключа официального API.

Что сделал

  • Собрал рубрикатор как дерево, а не плоский список: группы, подразделы и конечные рубрики, по которым справочник уже показывает организации.
  • Сделал сбор организаций по городу и рубрике: и сам список, и содержимое карточек — адрес, телефоны, почта, мессенджеры, график, ссылки, картинки.
  • Научил парсер догружать длинный список, который открывается только по мере прокрутки, и честно идти по страницам с номерами.
  • Разобрал служебные ссылки-перехваты: в результат уходит настоящий адрес сайта или диалога, а внутренняя аналитика площадки остаётся за кадром.
  • Собрал всё это только на открытых страницах: без входа в аккаунт, без ключей и без платного доступа к API.
  • Логику разбора проверил офлайн-тестами, которые запускаются без браузера и без сети.

Моя роль

Спроектировал и написал парсер, покрыл логику разбора тестами, описал форматы результата и правила запуска.

Результат

  • Парсер рубрикатора и парсер организаций публичного зелёного справочника.
  • Режим прогона по всем столицам регионов: одна таблица, без повторов, с продолжением после остановки.
  • Готовый датасет с описанием источника и инструкцией по запуску.

Что можно проверить

  • Парсер собирает публичные рубрики и организации по заданным городам
  • Логику разбора страниц справочника проверяют 33 теста без браузера и сети · 14.09.2026
  • Допуск только публичных ссылок и распознавание проверки «я не робот» закреплены тестами

Задача

Каталог публичного зелёного справочника огромен, но штатной выгрузки из него нет: рубрики и организации доступны только как страницы сайта, которые кто-то должен пролистать руками. Нужна была вся структура рубрик и полный список организаций по заданным городам — целиком и без ощущения, что что-то пропустили.

И главное условие: обойтись без ключа официального API, работая только с тем, что справочник отдаёт всем без входа.

Важно было и то, в каком виде эти данные приходят. Список организаций догружается по мере прокрутки, часть ссылок лежит на странице скрытыми копиями, а вместо обычных адресов сайтов и мессенджеров справочник показывает служебные ссылки-перехваты. Просто сохранить страницу означало получить мусор, поэтому каждую такую деталь пришлось разбирать отдельно.

Как собирается рубрикатор

Сбор начинается с города: справочник отдаёт список городов обычными ссылками, и по ним парсер выбирает нужный — по названию, короткому адресу или готовой ссылке. Если название подходит сразу нескольким городам, сбор не угадывает, а останавливается с понятной ошибкой: лучше явно остановиться, чем тихо собрать базу не того города.

Дальше идёт сам рубрикатор. Это не плоский список, а дерево: крупные группы вроде автосервисов или кафе, внутри них подразделы, а внизу — конечные рубрики, по которым справочник уже показывает организации. Парсер проходит по этому дереву как по оглавлению: зашёл в группу, собрал её подразделы, спустился глубже. Для каждой записи хранит название, публичную ссылку, тип (группа это или конечная рубрика), родителя и глубину. Из этого дерево можно восстановить целиком и пройти его программой, а не пересобирать руками по списку названий.

Как собирается список организаций

Выбираешь город и рубрику — справочник показывает список организаций. Самая неочевидная часть тут — длина этого списка. Страница не отдаёт карточки, пока их не прокручиваешь, поэтому парсер прокручивает колонку и ждёт, пока список перестанет пополняться: только тогда он считается собранным. Если у рубрики есть обычные страницы с номерами, парсер идёт по ним, но нажимает только на видимую ссылку-номер: такие ссылки бывают продублированы на странице в скрытом виде, а переход прямо по адресу иногда уводит не туда, куда нужно.

Потом открываются карточки: название, адрес, телефоны и почта, кнопки мессенджеров, график работы, ссылки и изображения. Повторы из списка убираются — одна и та же организация не попадает в результат дважды, — а название берётся первое непустое, чтобы в базе не оказалось пустых строк. Когда нужен охват, а не содержимое, есть щадящий режим: собрать только список организаций, не открывая каждую карточку.

Что делает результат чистым

Кнопки мессенджеров в карточке ведут не на диалог, а на служебный перехват, в адресе которого зашита внутренняя аналитика площадки. Парсер распутывает такой адрес на месте, без перехода по ссылке и без лишних запросов, и берёт из него только настоящий адрес диалога — он и уходит в контакты. Всё остальное, что там лежало, в результат не попадает. Так же разбираются и ссылки сайтов: служебный перехват заменяется нормальным адресом или видимой надписью.

Сбор идёт только по уже отрисованной странице: парсер не заглядывает в cookies, локальное хранилище браузера, служебные заголовки и чужие ключи доступа, а каждый запуск стартует в чистом окне — так в данные не попадает ничего, что относится к учётной записи человека, а не к открытому каталогу.

И главное: парсер не выдаёт неполный результат за полный. Если очередная страница оказалась пустой, карточка не пришла или одна страница повторилась, файл не создаётся и не обновляется — лучше явная ошибка, чем база, в которой тихо не хватает части организаций. При этом на долгом сборе файл целиком перезаписывается после каждой завершённой организации, поэтому запуск, остановленный посреди ночи, оставляет аккуратный читаемый файл с тем, что уже собрано.

Почему это работает без ключа

Вся ценность тут в том, что сбор идёт по открытому интерфейсу: ни входа в аккаунт, ни ключа официального API, ни платного тарифа не нужно. Результат не зависит от того, выдаст ли вообще площадка доступ, не упирается в лимиты ключа и не перестаёт работать, когда ключ кончится или сменит тариф.

Плата за это — честная рамка: чего нет на открытой странице, того нет и в результате. Поле, которое справочник отдаёт только через свой закрытый доступ, я не достану и обещать не буду. Поэтому сначала смотрю, что по конкретной рубрике реально показывает открытая страница, и только потом считаю это готовой базой.

Прогон по всем столицам регионов

Отдельная ветка того же проекта — прогон сразу по всем столицам регионов: набор поисковых фраз проходит по каждой из них, а результат дописывается в одну таблицу без повторов — город, фраза, название, телефоны, почта, мессенджеры и ссылка на карточку. Такой запуск можно остановить и продолжить: сборщик сверяет сохранённые строки со списком городов и фраз и продолжает с самой дальней пары, а не с начала. Если попадается проверка «я не робот», оконный режим просто ждёт, пока человек её пройдёт, — обходом защит я не занимаюсь.

Чем это подтверждено

Логику разбора — какие ссылки считать городом, какие рубрики относятся к справочнику, как читать страницы со списком организаций, как распаковать ссылку-перехват и что делать, если собрано не всё, — проверяют 33 теста. Они запускаются без браузера и без сети, поэтому любую доработку можно проверить за секунды и увидеть, что прежние сценарии не сломались. Результат сборки описан в документации проекта: какие поля куда ложатся, как выглядят файлы рубрик и организаций и как запускать каждый режим.

Кому пригодится

Когда нужно построить свою базу организаций, сравнить, как районы и города покрыты компаниями, посмотреть, как конкуренты разложены по рубрикам, или подготовить данные для импорта в другую систему — и не покупая для этого доступ к API. Тот же подход лежит в основе более крупных проектов — например, Стройрадар.

Обозначу рамки

Это открытые страницы публичного зелёного справочника, а не выкачка его закрытой базы: берётся ровно то, что видно без входа в аккаунт и без ключа. Массовые базы под рассылки из такого результата не делаю. Полнота сбора зависит от доступности и разметки источника — правила площадки задают потолок, и я их не обхожу.

Связанные услуги

Сбор и парсинг данных из реестров и сайтов

  • Python
  • Playwright
  • утилиты командной строки
  • тесты без сети