Когда я говорю «парсинг», большинство представляет строчку curl | grep. Реальность сложнее.
Google Maps отдаёт данные через JavaScript, Яндекс.Карты требуют Selenium с обходом детекта, 2GIS банит после десятого запроса, а EGRUL возвращает максимум 2000 записей за раз. Собрать 500 контактов автосервисов Москвы с телефонами, сайтами, email'ами и ФИО руководителя — это не curl. Это 8 разных движков, работающих параллельно.
Зачем мы это построили
B2B-продажи начинаются с контактов. Менеджер открывает 2GIS, копирует телефоны, потом Яндекс.Карты — смотрит рейтинг, потом EGRUL — проверяет ИНН. Три вкладки, час работы, 30 контактов. Данные разрознены: Яндекс даёт рейтинг, 2GIS — телефон и часы работы, EGRUL — ОГРН и выручку. Ни один источник не даёт полную картину.
Готовые SaaS закрыты. Ты не можешь залезть под капот, не можешь добавить свой источник, не можешь кастомизировать экспорт. Ты платишь $50-200 в месяц и надеешься что их прокси не забанят через неделю.
Мы решили построить свой комбайн. Открытый, расширяемый, заточенный под русский/CIS рынок. 528 Python-модулей спустя — вот что получилось.
Стек и архитектура
Ядро — Python 3.12 с asyncio. Почему не Scrapy? Scrapy хорош для простого HTTP-скрапинга, но ломается на JavaScript-рендеринге. А Google Maps и Zoon — чистый JavaScript. Выбор пал на связку Playwright + Selenium + aiohttp.
Ключевые решения:
- Playwright — для Google Maps, Zoon, Avito. Динамические карты, скролл-подгрузка, JavaScript.
- Selenium + undetected-chromedriver — для Яндекс.Карт. Патченый chromedriver, selenium-stealth.
- Чистый requests/aiohttp — для EGRUL (налоговая API), HH.ru (REST API). Где есть API — используем API.
- t.me/s scraping — для Telegram. Публичные каналы, никаких API-ключей, просто парсинг HTML.
- SQLite с WAL — не Postgres. Быстрее на чтение, не требует сервера, идеально для single-machine деплоя.
- Flask — веб-дашборд и REST API. Один self-contained файл с HTML/CSS/JS внутри.
Пайплайн обработки:
9 источников — 9 стратегий обхода защиты
Каждый источник парсится по-своему. Нет универсального подхода.
| Источник | Движок | Сложность | Что даёт |
|---|---|---|---|
| Google Maps | Playwright + regex | Высокая | Название, адрес, телефон, сайт, рейтинг, категория |
| Yandex Maps | Selenium + CSS | Высокая | Название, адрес, телефон, сайт, рейтинг, отзывы |
| 2GIS | API + Selenium fallback | Средняя | Название, телефон, сайт, часы работы, категория |
| Zoon.ru | Playwright + regex | Средняя | Название, телефон, сайт, рейтинг |
| Avito | Playwright | Высокая | Объявления, цены, категории |
| HH.ru | REST API | Низкая | Вакансии, зарплаты, скиллы |
| EGRUL | requests (API) | Низкая | ИНН, ОГРН, выручка, дата регистрации |
| OKVED | API + классификатор | Средняя | 600+ кодов ОКВЭД, поиск компаний по отрасли |
| Telegram | t.me/s scraping | Низкая | Заказы на сайты из фриланс-каналов |
Главная боль — Google Maps. После 3-5 запросов без маскировки прилетает капча, а через 10 — блокировка по IP. Каждый запрос должен выглядеть как человеческий. Случайная задержка 0.5-3 секунды с джиттером ±50%. Рандомный User-Agent из пула. Прокси ротируется при первых признаках блокировки.
Anti-detection: 4 слоя защиты
Промышленный парсинг — это гонка вооружений. Платформы защищаются, мы обходим.
Слой 1: Browser Fingerprint
undetected-chromedriver патчит Chrome чтобы скрыть автоматизацию. selenium-stealth маскирует WebDriver-флаги, navigator.webdriver, headless-режим. Playwright конфигурируется с реалистичными viewport, language, timezone. Отдельный контекст браузера на каждый источник — чтобы fingerprint не переиспользовался.
Слой 2: Прокси-ротация
Бесплатные прокси умирают быстро. Мы написали автосборщик — он собирает прокси из 8 публичных источников, валидирует их (latency + проверка через api.hh.ru), отбрасывает мёртвые. При 3 фейлах подряд прокси уходит в blacklist. Живые сортируются по latency — быстрейшие идут в начало очереди.
Слой 3: Поведенческий джиттер
Робот делает 50 запросов в секунду с интервалом ровно 1.0с. Человек — 5 запросов с интервалами 0.7с, 1.3с, 2.1с, 0.5с, 1.8с. Разница — это джиттер. Каждая задержка умножается на случайный коэффициент от 0.5 до 1.5. Плюс случайные «паузы на подумать» каждые 10-15 запросов.
Слой 4: Капча
Интеграция с rucaptcha/2captcha. Автоматический разбор reCAPTCHA v2, hCaptcha, изображений. До 3 попыток с увеличивающейся задержкой при ошибке. Если капча появляется слишком часто — источник временно отключается через Circuit Breaker.
OSINT-обогащение: 7 модулей в параллель
Собрать контакты — полдела. Их надо обогатить. После сбора карточка компании прогоняется через 7 OSINT-модулей:
- theHarvester — email'ы, поддомены, имена сотрудников из поисковиков и публичных DNS.
- PhoneInfoga — оператор связи, страна, регион, тип линии. Проверка в соцсетях по номеру.
- Holehe — проверка email на 120+ сайтах через функцию «забыл пароль». Без уведомления владельца.
- Hunter.io — корпоративные email'ы по домену: паттерн, confidence, имя и фамилия сотрудника.
- Maigret — поиск username по 25+ соцсетям. Полезно для поиска владельцев бизнеса.
- HIBP — проверка email в базе утечек. Какие данные утекли и когда.
- Shodan — открытые порты, сервисы, версии, уязвимости. IP, ISP, страна, ОС.
Плюс LPR (поиск ФИО руководителя через nalog.ru) — критично для B2B: звонить не на ресепшен, а директору. И DaData для стандартизации адресов.
Лид-скоринг
500 контактов — это много. Какие горячие? Система скоринга оценивает каждый по 7 факторам:
- Телефон — 25 баллов
- Сайт — 20 баллов
- Email — 20 баллов
- ИНН (юридическая проверка) — 15 баллов
- LPR (ФИО руководителя) — 15 баллов
- Адрес — 10 баллов
- Рейтинг — 10 баллов
Результат — 4 тира: A (80+, Hot) — телефон + сайт + email + ИНН + LPR, готов к звонку. B (60-79, Warm) — телефон + сайт, можно работать. C (40-59, Cold) — только телефон, нужен дообзвон. D (<40, Research) — минимум данных, на исследование рынка.
Экспорт в CRM-формате: колонки Company, Phone, Website, Email, Address, INN, Decision Maker, Position, Rating, Reviews. Готово к загрузке в любую CRM.
15 подпроектов
Кроме ядра, в проекте живут 15 самостоятельных парсеров. Каждый можно запустить отдельно:
- 2GIS Parser (две версии!) — GUI на Tkinter + CLI. 16+ стран. CSV/XLSX/JSON/HTML. Chrome-обход.
- CIAN Parser — недвижимость, pip-installable. CloudFlare bypass (CloudScraper). 54 страницы макс.
- Avito Parser — мониторинг объявлений в реальном времени. Docker + Telegram/VK-уведомления.
- HH.ru Research — анализ рынка вакансий. ML-предиктор зарплат для вакансий без цены.
- Review Parser — сбор отзывов с 2GIS + Google + Yandex + Zoon. Анализ трендов.
- OKVED Parser — 3-шаговый конвейер: налоговая → ФИО руководителя → лицензии ФСТЭК.
- И ещё 9: Yandex Reviews, Yandex Maps, EGRUL PDF, Google Maps Scraper, Maigret, Holehe, Sherlock, PhoneInfoga, Maps Parser.
Бизнес-применение
Допустим, ты продаёшь CRM для автосервисов. Твоя задача — найти все автосервисы Москвы с телефонами, сайтами и email'ами.
Ручной сбор: Открываешь 2GIS → вбиваешь «автосервис Москва» → копируешь первые 30 контактов. Потом Яндекс.Карты — ещё 20. Потом Гугл — ещё 15. 3 часа. Часть телефонов в разном формате, часть сайтов битая. Данные не склеены.
Parser Combine: Одна команда в CLI: python run.py search "автосервис" --city "москва" --max 200 --export csv. 5 минут — 500+ контактов с телефонами, сайтами, email'ами, рейтингами, ИНН. Данные склеены, дедуплицированы, отсортированы по качеству. Экспортированы в CSV для CRM.
Экономия: 3 часа → 5 минут. 30 контактов → 500+.
Заключение
Парсинг — это инфраструктура для продаж. Как CRM, как телефония, как email-рассылка. Если ты в B2B, тебе нужен поток контактов. И либо ты платишь $200/мес за закрытый SaaS с чужими прокси, либо строишь свой комбайн.
Мы построили свой. 528 Python-модулей. 9 источников. 7 OSINT-модулей. 15 подпроектов. Docker из коробки. Он работает, расширяется и не зависит от вендора.
Если вам нужна автоматизация сбора данных — посмотрите кейс или напишите мне. Разберём вашу задачу.