Skip to content

feewwee39-dev/lead-parser

Repository files navigation

lead-parser — парсер лидов для холодных продаж

Автоматизированный инструмент лидогенерации для малого бизнеса. Парсит Яндекс.Карты, находит заведения с негативными отзывами по конкретным болям (запись, ожидание, хамство, потеря клиента) и генерирует персонализированный скрипт холодного диалога под каждый лид.

Результат: готовый текст первого сообщения в WhatsApp/Telegram — деловой, конкретный, без рекламного тона. Упоминает реальную ситуацию из отзыва клиента.


Как это работает

Яндекс.Карты
     │
     ▼
[scraper_yandex.py]  ──  headless Chromium, обходит JS-рендеринг
     │
     ├─ фильтр: рейтинг 3.0–4.6 ★, есть WhatsApp или Telegram
     │
     ▼
[card_cache.py]  ──  кэш ~800+ карточек, повторный запуск не парсит заново
     │
     ▼
[dialog_gen.py]  ──  классификация боли → детерминированный MSG1
     │
     └─ опционально: LM Studio (Gemma 4) улучшает формулировку
     │
     ▼
output/leads_*.txt  ──  структурированный лид с контактами и скриптом

Классификация болей (8 типов)

Скрипт не ищет просто плохие отзывы — он определяет конкретную проблему, под которую составляется уникальное первое сообщение:

Тип Что означает Пример отзыва
no_response Не берут трубку / не перезванивают «не дозвонился, так и не записался»
no_show Пришёл — заведение закрыто «приехал по записи, дверь закрыта»
cancellation Отменили/перенесли без предупреждения «запись отменили, не сообщили»
waiting Ждал больше 30 минут «опоздали на час, не извинились»
lost_booking Запись потерялась «пришёл — в расписании нет»
phone_rude Нагрубили по телефону «оператор накричал»
wrong_result Сделали не то, что просили «просил не трогать виски — обкарнали»
general Общее недовольство всё остальное

Примеры сгенерированных сообщений

[no_response]
Видел отзыв у вас в Краснодаре — клиент пишет, что не смог дозвониться,
так и не записался. В часы пик часто такое?

[cancellation]
Видел отзыв у вас — запись перенесли или отменили, но клиенту не сообщили.
Это вручную приходится всех обзванивать?

[wrong_result]
Видел отзыв у вас — клиент просил одно, мастер сделал иначе.
Пожелания при записи как-то фиксируете, или всё устно?

Ни одно сообщение не содержит слов «предлагаем», «автоматизация», «бот». Тон — коллега, который заметил что-то в отзыве, не продавец.


Структура проекта

├── _fast5.py            # быстрый прогон: 5 лидов по 40+ городам
├── _run_leads_new.py    # полный прогон: 20 лидов
├── scraper_yandex.py    # парсер Яндекс.Карт (headless Playwright)
├── scraper_2gis.py      # парсер 2ГИС (альтернатива)
├── scraper_google.py    # парсер Google Maps
├── dialog_gen.py        # классификация боли + генерация скрипта
├── card_cache.py        # JSON-кэш карточек (output/cache_parsed.json)
├── models.py            # BusinessCard, Review, Phone
├── analyzer.py          # анализ собранных данных
├── export_leads.py      # экспорт лидов
├── messages.py          # шаблоны сообщений
├── main.py              # CLI-точка входа (парсинг через config.json)
├── config.json          # конфиг задач
├── requirements.txt
└── output/
    ├── cache_parsed.json   # кэш (не коммитится)
    ├── leads_fast5.txt     # результаты быстрого прогона
    └── leads_new_20.txt    # результаты полного прогона

Быстрый старт

git clone https://github.com/feewwee39-dev/lead-parser.git
cd lead-parser

pip install -r requirements.txt
playwright install chromium

Запуск быстрого прогона (5 лидов)

$env:PYTHONUTF8="1"
python -X utf8 _fast5.py

Результат записывается в output/leads_fast5.txt в реальном времени.

Мониторинг лога

tail -f output/_fast5_log.txt

Полный прогон (20 лидов)

$env:PYTHONUTF8="1"
python -X utf8 _run_leads_new.py

Параметры парсера (_fast5.py)

Параметр Значение Описание
CITIES 40+ городов Краснодар, Воронеж, Самара, Уфа, Архангельск и др.
RATING_MIN / RATING_MAX 3.0 – 4.6 Ищем тех, у кого есть проблемы, но не провальных
MIN_NEG / MAX_NEG 1 – 6 Минимум 1 негативный отзыв, не более 6
MAX_REVIEWS 15 Сколько отзывов читать с карточки
NEED 5 Сколько лидов нужно найти за прогон
Задержка 0.2–0.4 с Между карточками (anti-ban)
URL на город 30 Максимум карточек на поисковый запрос

Обязательное условие лида: наличие WhatsApp или Telegram у заведения.


LM Studio (опционально)

Если запущен LM Studio с любой локальной моделью — скрипт автоматически улучшает формулировку MSG1, сохраняя деловой стиль. При недоступности LM Studio используется детерминированный шаблон (работает не хуже).

LM_HOST  = "http://localhost:1234"
LM_MODEL = "local-model"

Протестировано с Gemma 4 (27B). Модель настроена на однострочный ответ без рассуждений.


Пример вывода лида

────────────────────────────────────────────────────────────────────────
ЛИД #1  [WA+TG]  |  Barber Culture  |  Тамбов  |  *4.0
Адрес   : ул. Советская, 153
Тел     : +7 920 000-00-00
WA      : https://wa.me/79200000000
TG      : https://t.me/barberculture
Ссылка  : https://yandex.ru/maps/...
Запись  : только звонки/мессенджеры
Негативных: 2  |  боль: 1

НЕГАТИВНЫЕ ОТЗЫВЫ:
  1. *2  Иван К. [БОЛЬ]
     Просил не трогать виски — мастер обкарнал до нуля. На замечание
     ответил что "так лучше выглядит".

БОЛЬ: «просил не трогать виски — мастер обкарнал»

СКРИПТ:
........................................................................
Видел отзыв у вас — клиент просил одно, мастер сделал иначе.
Пожелания при записи как-то фиксируете, или всё устно?
........................................................................

Технологии

Слой Технология
Парсинг Python 3.12 + Playwright (async, headless Chromium)
Источники Яндекс.Карты, 2ГИС, Google Maps
Кэш JSON (~800+ карточек, персистентный между запусками)
NLP Детерминированная классификация по ключевым словам
LLM (опц.) LM Studio / OpenAI-совместимый API (локально)
Вывод Структурированный TXT с полным скриптом диалога

Для чего это нужно

Инструмент создан для холодных продаж Telegram мини-приложения записи барбершопам и салонам (1 500 ₽ под ключ). Скрипт находит заведения, где уже есть подтверждённая боль в отзывах, и формирует первое сообщение, которое попадает в конкретную проблему — не шаблонный спам.

Воронка: парсер → MSG1 (боль) → MSG2 (вопрос о текущей записи) → MSG3 (уточнение) → MSG4 (питч) → MSG5 (демо за 1 минуту).

About

Парсер лидов: Яндекс.Карты + классификация болей + скрипт холодного диалога

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages