Библиотека · Маркетинг, продажи и аналитика на AI

Поиск потенциальных клиентов — от сбора данных с сайтов до таблицы CSV

Строитель110 минОбновлено: октябрь 2026
65 из 105 в библиотеке

Время: ~20 мин теории + 90 мин практики


Суть урока

🎨 Образ: Lead Generation System — как ночная смена на заводе. Пока ты спишь, конвейер собирает, проверяет и упаковывает готовую продукцию. Утром на столе — коробки с именами, адресами и краткой биографией каждого клиента.

Представь что ты можешь нанять сотрудника который за ночь собирает 500 контактов потенциальных клиентов (лидов — потенциальных клиентов), заходит на сайт каждого из них, читает про бизнес, формулирует персонализированный icebreaker (айсбрейкер — фраза для начала разговора) — и утром кладёт тебе готовый CSV. Именно это делает Lead Generation System на Claude Code. Это полноценная B2B (би-ту-би — продажи бизнесу) автоматизация: от пустого списка до обогащённой базы с которой можно сразу идти в холодный аутрич (контакт с незнакомым потенциальным клиентом).


Ключевые концепции

  • Lead Generation Pipeline (пайплайн генерации лидов — конвейер обработки) — 4 этапа: сбор → фильтрация → обогащение → экспорт
  • Apify — маркетплейс scrapers (скрейперов — программ-сборщиков данных), Google Maps scraper для поиска бизнесов по нише и локации
  • Фильтрация — оставляем только лидов с сайтом и телефоном (остальные отбрасываем)
  • Enrichment (энричмент — обогащение данных) — Claude анализирует каждый сайт: value proposition (вэлью пропозишн — ценностное предложение), уникальность, кейс стади (разбор реального проекта с результатами)
  • Output (аутпут — результат на выходе) — CSV с полями: company, location, website, phone, value_prop, differentiator, case_study
  • Skill (скилл — навык, переиспользуемый модуль Claude) — весь пайплайн упаковывается в переиспользуемый скилл с slash-командой

Теория

Структура пайплайна

🎨 Образ: Пайплайн — как нефтяная труба из четырёх секций. Каждая секция очищает сырьё: сначала добываем (scrape), потом фильтруем примеси (только с сайтом и телефоном), потом обогащаем (Claude читает каждый сайт), потом разливаем по бутылкам (CSV). На выходе — не нефть, а бензин.

Код
Вход:
  niche = "roofing companies"
  location = "North Carolina"
  count = 30

Шаг 1: Google Maps Scraping (Apify)
  → 34 бизнеса с метаданными Google Maps

Шаг 2: Фильтрация
  → Оставляем только: website AND phone существуют
  → Например: 22 из 34 прошли фильтр

Шаг 3: Website Scraping + Claude Enrichment
  → Для каждого из 22: scrape homepage + /about + /services
  → Claude извлекает: value_prop, differentiator, case_study
  
Шаг 4: CSV Export
  → leads.csv — готово для Google Sheets и CRM

Почему Apify, а не прямой парсинг Google

🎨 Образ: Apify — как профессиональный рыбацкий траулер. Ты мог бы плавать сам с удочкой (парсить Google напрямую) — но тебя быстро поймают и выгонят. Траулер с лицензией работает в открытом море и возвращает полный улов в структурированном виде.

У Google Maps есть официальный платный API (эй-пи-ай — интерфейс программирования), но он не рассчитан на выгрузку баз бизнесов в больших объёмах. Прямой скрейпинг страниц Google — нарушение ToS (Terms of Service — условий использования) и быстрая блокировка. Условия сервисов меняются: перед запуском проверь актуальные условия и законы своей страны.

Apify — это маркетплейс готовых scrapers с:

  • Ротацией прокси (обход блокировок)
  • Управлением лимитами
  • Структурированным выходом (JSON)
  • Бесплатным тарифом с небольшим ежемесячным кредитом (актуальные условия: apify.com/pricing)

Google Maps scraper на Apify принимает запрос типа "roofing companies near North Carolina" и возвращает список бизнесов с адресом, сайтом, телефоном, рейтингом, часами работы.


Начальный промпт (запрос к AI): объяснение задачи Claude Code

Важный паттерн из практики: сначала описывай задачу полностью, не указывай сразу "создай скилл". Пусть Claude сначала построит и протестирует систему, потом упакует в скилл:

Напиши в чат
Hey, задача сегодня — создать Lead Generation System.

Шаг 1: я даю нишу, локацию и количество результатов
Шаг 2: ты идёшь в Apify и используешь Google Maps scraper
Шаг 3: фильтруешь — оставляешь только лидов С сайтом и телефоном
Шаг 4: заходишь на каждый сайт (homepage + about + services)
Шаг 5: Claude извлекает: value proposition, чем уникальны, кейс-стади клиентов
Шаг 6: выдаёшь CSV: company_name, location, website, phone, value_prop, differentiator, case_study

Задай уточняющие вопросы перед началом.

Claude уточнит: есть ли API ключ Apify, какой формат вывода предпочесть, какой язык использовать.


Python скрипт: архитектура системы

python
# lead_generation.py
import os
import csv
import json
import anthropic
from apify_client import ApifyClient

APIFY_TOKEN = os.environ["APIFY_API_TOKEN"]
ANTHROPIC_API_KEY = os.environ["ANTHROPIC_API_KEY"]

def scrape_google_maps(niche: str, location: str, count: int) -> list[dict]:
    """Шаг 1: Собираем бизнесы через Apify Google Maps scraper"""
    client = ApifyClient(APIFY_TOKEN)
    
    run_input = {
        "searchStringsArray": [f"{niche} near {location}"],
        "maxCrawledPlacesPerSearch": count,
        "language": "en",
        "countryCode": "us",
    }
    
    # Google Maps Scraper на Apify (compass/crawler-google-places)
    run = client.actor("nwua9Gu5YrADL7ZDj").call(run_input=run_input)
    
    results = []
    for item in client.dataset(run["defaultDatasetId"]).iterate_items():
        results.append({
            "company_name": item.get("title", ""),
            "location": item.get("address", ""),
            "website": item.get("website", ""),
            "phone": item.get("phone", ""),
            "rating": item.get("totalScore", ""),
        })
    
    return results


def filter_leads(raw_leads: list[dict]) -> list[dict]:
    """Шаг 2: Оставляем только лидов с сайтом и телефоном"""
    filtered = [
        lead for lead in raw_leads
        if lead.get("website") and lead.get("phone")
    ]
    print(f"Фильтрация: {len(raw_leads)} → {len(filtered)} лидов")
    return filtered


def scrape_website(url: str) -> str:
    """Шаг 3а: Собираем текст с сайта (homepage + about + services)"""
    import requests
    from bs4 import BeautifulSoup
    
    pages_to_scrape = [url, f"{url}/about", f"{url}/services"]
    all_text = []
    
    for page_url in pages_to_scrape:
        try:
            response = requests.get(page_url, timeout=10, headers={
                "User-Agent": "Mozilla/5.0 (compatible; LeadBot/1.0)"
            })
            if response.status_code == 200:
                soup = BeautifulSoup(response.text, "html.parser")
                # Убираем скрипты и стили
                for tag in soup(["script", "style", "nav", "footer"]):
                    tag.decompose()
                text = soup.get_text(separator=" ", strip=True)
                all_text.append(text[:2000])  # Берём первые 2000 символов каждой страницы
        except Exception:
            continue
    
    return " | ".join(all_text)


def enrich_with_claude(company_name: str, website_text: str) -> dict:
    """Шаг 3б: Claude извлекает structured insights из текста сайта"""
    client = anthropic.Anthropic(api_key=ANTHROPIC_API_KEY)
    
    message = client.messages.create(
        model="claude-haiku-4-5",  # Haiku достаточно для структурного извлечения; актуальные модели: страница Актуальное сейчас
        max_tokens=500,
        messages=[{
            "role": "user",
            "content": f"""Проанализируй этот текст с сайта компании {company_name}.

Текст сайта:
{website_text[:3000]}

Извлеки в JSON:
- value_prop: основное ценностное предложение (1-2 предложения)
- differentiator: чем они уникальны среди конкурентов (1 предложение)
- case_study: имя клиента и суть кейса если есть на сайте, иначе null

Верни только JSON без markdown.
"""
        }]
    )
    
    try:
        return json.loads("".join(b.text for b in message.content if b.type == "text"))
    except json.JSONDecodeError:
        return {
            "value_prop": "N/A",
            "differentiator": "N/A",
            "case_study": None
        }


def export_to_csv(leads: list[dict], filename: str = "leads.csv") -> None:
    """Шаг 4: Экспорт в CSV"""
    if not leads:
        print("Нет лидов для экспорта")
        return
    
    fieldnames = ["company_name", "location", "website", "phone",
                  "value_prop", "differentiator", "case_study"]
    
    with open(filename, "w", newline="", encoding="utf-8") as f:
        writer = csv.DictWriter(f, fieldnames=fieldnames)
        writer.writeheader()
        for lead in leads:
            # Убеждаемся что все поля на месте (защита от смещения колонок)
            row = {field: lead.get(field, "") for field in fieldnames}
            writer.writerow(row)
    
    print(f"Экспортировано {len(leads)} лидов в {filename}")


def run_pipeline(niche: str, location: str, count: int, output_file: str) -> None:
    """Запуск полного пайплайна"""
    print(f"Запуск: {niche} в {location}, {count} результатов")
    
    # Шаг 1: Scraping
    raw_leads = scrape_google_maps(niche, location, count)
    
    # Шаг 2: Фильтрация
    filtered_leads = filter_leads(raw_leads)
    
    # Шаг 3: Enrichment
    enriched_leads = []
    for i, lead in enumerate(filtered_leads):
        print(f"  Обогащаю {i+1}/{len(filtered_leads)}: {lead['company_name']}")
        website_text = scrape_website(lead["website"])
        enrichment = enrich_with_claude(lead["company_name"], website_text)
        enriched_leads.append({**lead, **enrichment})
    
    # Шаг 4: Export
    export_to_csv(enriched_leads, output_file)
    print("Готово!")


if __name__ == "__main__":
    run_pipeline(
        niche="roofing companies",
        location="North Carolina",
        count=30,
        output_file="leads.csv"
    )

Реальный вывод: что получается в CSV

После запуска система выдаёт файл с такими данными:

company_name location website phone value_prop differentiator case_study
Example Roofing Co Charlotte, NC example.com +1-555-0100 Комплексный кровельный сервис с семейным подходом и финансированием Семейная компания, опыт работы указан на сайте Клиент: полная реновация кровли завершена без задержек
... ... ... ... ... ... ...

Строка выше вымышленная, для примера. Этот CSV идёт в Google Sheets через File → Import (если всё попало в одну колонку, поможет Data → Split text to columns).


Упаковка в скилл + slash-команду

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

После того как система работает, просишь Claude Code создать из неё скилл:

Напиши в чат
Теперь что я прошёл через весь этот пайплайн — создай скилл 
с названием "lead-generation-system" чтобы я мог вызывать его 
как slash-команду /lead-generation-system.

Claude создаёт структуру:

Код
.claude/skills/lead-generation-system/
├── SKILL.md          ← описание + инструкции для Claude
├── scripts/
│   └── lead_generation.py
└── references/
    ├── requirements.txt
    └── sample_output.csv

Навык сам становится slash-командой: теперь можно набрать /lead-generation-system и система спросит нишу, локацию, количество. Отдельный файл в .claude/commands/ больше не обязателен: команды и навыки объединены, старые файлы команд продолжают работать. Чтобы навык был доступен в любом проекте, положи его в личную папку ~/.claude/skills/.


Этические ограничения

Допустимо Запрещено
Публичные данные из Google Maps Email адреса физических лиц
Публичный текст корпоративных сайтов Личные данные владельцев
Бизнес-телефоны из открытых источников Обход CAPTCHAs агрессивно
Анализ публичных кейс-стади Данные из приватных разделов сайтов

Система собирает только то что бизнес сам публично разместил в интернете — обычно это приемлемо для B2B аутрича. Правила о персональных данных и рассылках зависят от страны (например GDPR в Европе, CAN-SPAM в США, CASL в Канаде): перед рассылкой сверься с законом своей страны. Это не юридическая консультация.


Практика

Задание: Lead Generation для конкретной ниши

  1. Зарегистрируйся на apify.com, получи API токен (на бесплатном тарифе есть небольшой ежемесячный кредит, актуальные условия — на сайте Apify)
  2. Установи зависимости: pip install apify-client anthropic requests beautifulsoup4
  3. Попроси Claude Code построить упрощённую версию пайплайна для ниши которую выберешь:
    • "digital marketing agencies in Miami"
    • "yoga studios in Austin"
    • IT-компании в твоём городе (в нише, которую ты понимаешь)
  4. Запусти с count=10 для теста — убедись что CSV генерируется корректно
  5. Открой CSV в Google Sheets, проверь что все колонки на правильных местах
  6. Попроси Claude Code упаковать систему в скилл
  7. Бонус: добавь scoring колонку (0-100) где Claude оценивает качество лида на основе наличия case_study и детальности value_prop

Цель: с нуля до рабочей lead generation системы с реальными данными.


Инструменты и ресурсы

  • Apify — apify.com — маркетплейс scrapers, Google Maps scraper ID: nwua9Gu5YrADL7ZDj
  • apify-client — pip install apify-client — Python SDK для Apify
  • beautifulsoup4 — pip install beautifulsoup4 — парсинг HTML сайтов
  • requests — pip install requests — HTTP запросы к сайтам лидов
  • Google Sheets — Data → Split text to columns — открыть CSV
  • Hunter.io — hunter.io — поиск email по домену (есть бесплатный тариф с месячным лимитом кредитов, подробности на сайте), дополняет пайплайн контактными данными
  • Apollo.io — apollo.io — полная B2B база контактов с верификацией email, альтернатива Apify для лидов
  • LinkedIn Sales Navigator — business.linkedin.com/sales-solutions — таргетированный поиск ЛПР (условия пробного периода смотри на сайте)
  • Instantly.ai — instantly.ai — автоматизация отправки писем с прогревом домена (когда масштабируешь outreach)

Частые ошибки

🎨 Образ: Не фильтровать лидов перед enrichment — как обогащать руду вместе со щебнем. Дороже, дольше, и половина усилий уходит в мусор. Фильтруй сначала — обогащай только ценное.

  • Не фильтровать лидов перед enrichment. Обогащение каждого лида стоит денег (API call к Claude). Без фильтра ты тратишь бюджет на компании без сайта и телефона, которые невозможно контактировать. Фильтруй ПЕРЕД enrichment.
  • Не проверять CSV вручную. Первые 10 строк всегда проверяй глазами в Google Sheets. Смещение колонок, пустые поля, дубликаты — всё это ловится на ранних данных, но портит всю базу при масштабе.
  • Слишком большой count на старте. Начинай с count=10 для теста. Если сразу ставишь 500 — потратишь деньги на Apify и API Claude и много времени на enrichment. И обнаружишь ошибку в шаге 3. Сначала проверь цену и качество данных на маленьком запуске.
  • Не связывать лидов с outreach. CSV без действий — просто файл. Этот пайплайн питает холодный outreach (→ Холодный outreach с помощью Claude) и CRM (→ Google Sheets таблица из того же урока).

Связь с другими уроками


Ключевые выводы

Пайплайн из 4 шагов: Apify (scrape) → фильтр (website+phone) → Claude enrichment → CSV. Каждый шаг независим и тестируется отдельно.

Сначала строй и тести систему — потом проси Claude упаковать в скилл. Скилл созданный из работающей системы лучше скилла созданного "с воздуха".

Защита от смещения колонок в CSV: явно указывай fieldnames и используй lead.get(field, "") — это предотвращает проблему когда phone попадает в колонку location.


Следующий урок

→ Ценообразование: value-based pricing

Отметка хранится только в этом браузере и никуда не отправляется. Мой прогресс