Суть урока
Представь что ты можешь нанять сотрудника который за ночь собирает 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-командой
Теория
Структура пайплайна
Вход:
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
У 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 скрипт: архитектура системы
# 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 для конкретной ниши
- Зарегистрируйся на apify.com, получи API токен (на бесплатном тарифе есть небольшой ежемесячный кредит, актуальные условия — на сайте Apify)
- Установи зависимости:
pip install apify-client anthropic requests beautifulsoup4 - Попроси Claude Code построить упрощённую версию пайплайна для ниши которую выберешь:
- "digital marketing agencies in Miami"
- "yoga studios in Austin"
- IT-компании в твоём городе (в нише, которую ты понимаешь)
- Запусти с count=10 для теста — убедись что CSV генерируется корректно
- Открой CSV в Google Sheets, проверь что все колонки на правильных местах
- Попроси Claude Code упаковать систему в скилл
- Бонус: добавь 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. Обогащение каждого лида стоит денег (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 таблица из того же урока).
Связь с другими уроками
- → Первые клиенты — начни с тёплых контактов, Lead Gen добавь позже
- → Холодный outreach с помощью Claude — CSV из этого урока = входные данные для персонализированных писем
- → Реальные кейсы монетизации — Lead Gen пайплайн (рабочий процесс) как один из разборов
Ключевые выводы
Пайплайн из 4 шагов: Apify (scrape) → фильтр (website+phone) → Claude enrichment → CSV. Каждый шаг независим и тестируется отдельно.
Сначала строй и тести систему — потом проси Claude упаковать в скилл. Скилл созданный из работающей системы лучше скилла созданного "с воздуха".
Защита от смещения колонок в CSV: явно указывай
fieldnamesи используйlead.get(field, "")— это предотвращает проблему когда phone попадает в колонку location.
Следующий урок
Отметка хранится только в этом браузере и никуда не отправляется. Мой прогресс