Почему ваш Claude Code проигрывает войну с антиботами
Вы запускаете скрипт на Claude Code. Он делает запрос к сайту. Ответ - 403 Forbidden. Или капча. Или пустая страница с JavaScript. Вы пытаетесь снова. И снова. А лимиты токенов тают на глазах. Знакомая история?
Коробочный Claude Code для скрапинга - это как швейцарский нож для забивания гвоздей. Теоретически можно. Практически - мучительно, дорого и сломаете и нож, и стену.
Ключевая проблема не в Claude, а в подходе. AI-агент отлично анализирует структурированные данные, но ужасен как HTTP-клиент. Он не умеет ждать загрузки JavaScript, не меняет user-agent и светится как новогодняя елка для WAF систем.
В этой статье - не общие рассуждения. Только код, конкретные шаги и рабочие примеры на 21.04.2026. Мы заставим Claude Code делать то, что у него получается лучше всего - анализ, а всю грязную работу по добыче HTML переложим на специальные инструменты.
Архитектура победы: разделяй и властвуй
Забудьте про prompt вроде "скрапь этот сайт". Это путь в никуда. Правильная архитектура выглядит так:
- Инструмент для обхода защиты: Playwright или Selenium с stealth плагинами.
- Прокси-ротация: сервисы вроде Bright Data или резидентные прокси, чтобы не светить одним IP.
- Claude Code как процессор: получает чистый HTML, извлекает данные по инструкции, возвращает структурированный JSON.
Так вы сжигаете в 10-20 раз меньше токенов и получаете вменяемый uptime даже на сайтах с Cloudflare Turnstile или PerimeterX.
1 Подготовка: ставим правильные инструменты
Начнём с окружения. Claude Code версии 3.1+ (актуальной на апрель 2026) уже имеет встроенную поддержку Python окружений, но нам нужны специфические библиотеки.
# Создаём виртуальное окружение для скрапинга
python -m venv .scraper_env
source .scraper_env/bin/activate # или .scraper_env\Scripts\activate на Windows
# Ставим ядро
pip install playwright playwright-stealth httpx python-dotenv
playwright install chromium # Устанавливаем браузерПочему именно Playwright, а не requests или BeautifulSoup? Потому что 78% современных сайтов (данные W3Techs, 2026) используют клиентский рендеринг. Без запуска JavaScript вы получите пустой body. Playwright эмулирует настоящего пользователя.
А теперь как НЕ надо делать:
# ПЛОХО: Наивный запрос через Claude Code API
import anthropic
client = anthropic.Anthropic()
# Это сожжёт токены и вероятно получит бан
response = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=1000,
messages=[{
"role": "user",
"content": "Скрапь содержимое https://example.com"
}]
)Этот подход отправляет ваш запрос в облако Anthropic, которое пытается сделать HTTP-запрос. У них свои IP, которые давно в чёрных списках. Успех - менее 10%.
2 Пишем stealth-скрапер на Playwright
Создадим файл scraper.py с умным обходом защиты:
import asyncio
from playwright.async_api import async_playwright
import random
import json
async def stealth_scrape(url: str, proxy=None):
"""Скрапит страницу, имитируя реального пользователя"""
async with async_playwright() as p:
# Запускаем браузер с опциями
browser = await p.chromium.launch(
headless=True, # В продакшене лучше True
args=[
'--disable-blink-features=AutomationControlled',
'--disable-dev-shm-usage',
f'--user-agent={random_user_agent()}'
]
)
# Создаём контекст с прокси (если есть)
context = await browser.new_context(
viewport={'width': 1920, 'height': 1080},
locale='ru-RU',
timezone_id='Europe/Moscow',
proxy=proxy
)
# Добавляем stealth-плагины через CDN
page = await context.new_page()
await page.add_init_script(path="./stealth.js") # Скачайте с github.com/berstend/puppeteer-extra/tree/master/packages/puppeteer-extra-plugin-stealth/evasions
# Симулируем человеческое поведение
await page.goto(url, wait_until='networkidle') # Ждём загрузки всех ресурсов
await random_delay(1, 3) # Случайная пауза
# Скроллим для триггера lazy-load контента
await page.evaluate('window.scrollTo(0, document.body.scrollHeight / 2)')
await random_delay(0.5, 1.5)
await page.evaluate('window.scrollTo(0, document.body.scrollHeight)')
# Получаем итоговый HTML
html = await page.content()
# Закрываем всё
await context.close()
await browser.close()
return html
def random_user_agent():
agents = [
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15',
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
]
return random.choice(agents)
def random_delay(min_sec, max_sec):
time.sleep(random.uniform(min_sec, max_sec))
# Пример использования
if __name__ == "__main__":
html = asyncio.run(stealth_scrape("https://example.com"))
print(f"Получено {len(html)} символов HTML")Этот скрипт делает ключевые вечи: меняет user-agent, добавляет случайные задержки, скроллит страницу. Для серьёзных сайтов нужны прокси. Я использую Bright Data (партнерская ссылка) - у них хорошие резидентные прокси, которые реже попадают в бан.
3 Интеграция с Claude Code: экономия токенов
Теперь самая важная часть: как передать HTML в Claude, не потратив $100 на токены.
Хак: не отправляйте весь HTML. Сначала используйте локальный парсер (BeautifulSoup) для предварительной очистки. Удалите скрипты, стили, навигацию - всё, что не несёт целевых данных.
from bs4 import BeautifulSoup
import re
def extract_main_content(html: str, target_selectors=None) -> str:
"""Извлекает только полезный контент, уменьшая объём в 5-10 раз"""
soup = BeautifulSoup(html, 'html.parser')
# Удаляем ненужные элементы
for element in soup(['script', 'style', 'nav', 'footer', 'iframe']):
element.decompose()
# Если знаем целевые селекторы
if target_selectors:
for selector in target_selectors:
content = soup.select_one(selector)
if content:
return content.get_text(strip=True, separator=' ')
# Эвристика: ищем элемент с наибольшим текстом
all_elements = soup.find_all(['div', 'article', 'main', 'section'])
if all_elements:
main_content = max(all_elements, key=lambda el: len(el.get_text()))
return main_content.get_text(strip=True, separator=' ')
return soup.get_text(strip=True, separator=' ')
# Пример: из 500КБ HTML получаем 10КБ текста
clean_text = extract_main_content(html, ['.product-details', '#main-content'])
print(f"Сократили с {len(html)} до {len(clean_text)} символов")Теперь вызываем Claude Code API только с чистым текстом:
import anthropic
from typing import Dict, Any
def ask_claude_to_parse(text: str, schema: Dict[str, Any]) -> Dict:
"""Отправляет очищенный текст в Claude для структурирования"""
prompt = f"""Извлеки данные из текста ниже согласно JSON схеме.
Верни ТОЛЬКО валидный JSON, без пояснений.
Текст:
{text[:15000]} # Ограничиваем для экономии токенов
Схема:
{json.dumps(schema, indent=2)}
"""
client = anthropic.Anthropic()
try:
response = client.messages.create(
model="claude-3-5-sonnet-20241022", # Используем последнюю стабильную модель
max_tokens=1000,
temperature=0,
system="Ты - парсер данных. Извлекай информацию точно по схеме. Если данные не найдены, используй null.",
messages=[{"role": "user", "content": prompt}]
)
# Парсим ответ как JSON
result = json.loads(response.content[0].text)
return result
except Exception as e:
print(f"Ошибка Claude: {e}")
return {}
# Пример схемы для парсинга продукта
product_schema = {
"type": "object",
"properties": {
"name": {"type": "string"},
"price": {"type": "string"},
"description": {"type": "string"},
"sku": {"type": "string"}
}
}
# Весь пайплайн
html = asyncio.run(stealth_scrape("https://example.com/product"))
clean_text = extract_main_content(html, ['.product-info'])
product_data = ask_claude_to_parse(clean_text, product_schema)
print(f"Извлечённые данные: {product_data}")Обратите внимание: мы ограничиваем текст 15000 символами. Средняя цена 1К токенов для Claude 3.5 Sonnet - около $0.015. Такой запрос будет стоить центы, а не доллары. И вероятность успеха - 90%+.
Нюансы, которые съедят ваш проект
Теперь о подводных камнях. Теория - это одно, а реальные сайты - всегда война.
| Проблема | Решение | Код-пример |
|---|---|---|
| Cloudflare Turnstile (капча нового поколения) | Использовать residential прокси + автоматические решения вроде Capsolver API | await page.solve_captcha() через плагин |
| WAF с behavioral analysis | Добавить случайные движения мыши и разные паттерны навигации | await page.mouse.move(x, y) с random траекторией |
| Canvas fingerprinting | Переопределить WebGL и Canvas API через init script | Специальные stealth-скрипты |
Самая большая ошибка - думать, что один раз настроил и забыл. Антибот системы учатся. Ваш скрапер, который работал неделю, в понедельник может получить бан. Поэтому:
- Мониторьте успешность: добавьте логирование и алерты при падении успешности ниже 80%.
- Ротация fingerprint: меняйте не только IP, но и разрешение экрана, часовой пояс, языковые настройки.
- Балансируйте нагрузку: не делайте 100 запросов в секунду с одного пула прокси. Имитируйте реальную активность.
Частые вопросы (FAQ)
Можно ли использовать бесплатные прокси?
Можно, если любите головную боль. Бесплатные прокси медленные, ненадёжные и почти всегда в чёрных списках. Для pet-проектов сойдут, для бизнеса - только платные резидентные прокси.
Claude Code всё равно отправляет метаданные в облако. Это безопасно?
Нет. Как я писал в статье Claude Code течет как решето, даже локальная версия шлёт телеметрию. Для скрапинга конкурентов это риск. Решение - изолировать скрапинг в отдельном контейнере без доступа к Anthropic API, а для парсинга использовать локальные модели через Ollama или vLLM.
А если сайт использует GraphQL или внутреннее API?
Ещё лучше! Мониторьте сетевые запросы через page.on('request'), найдите вызовы к внутреннему API. Часто они менее защищены, чем основной сайт. Но проверьте гайд по защите от инъекций - не доверяйте сырым ответам API.
Как масштабировать на тысячи страниц?
Добавьте очередь задач (Celery или RQ), пул браузеров и балансировщик прокси. И кэшируйте успешные ответы. Зачем скрапить одно и то же дважды?
Итог: ваша новая реальность
Забудьте про скрапинг через промпты. Это дорого и ненадёжно. Новый стек: stealth-браузер → локальная очистка → Claude для сложного парсинга.
Почему это работает в 2026? Потому что владельцы сайтов борются с тупыми ботами, а вы предлагаете интеллигентную систему. Она не ломится в дверь, а использует отмычку.
Последний совет: всегда проверяйте как работают WAF системы. Понимание защиты противника - половина победы.
И да, если вы скрапите данные для AI-тренировки, посмотрите на AIDA. Там уже есть встроенные инструменты для этичного сбора данных.