Почему происходит обнаружение
Обнаружение веб-скрапинга — это многоуровневый процесс. Антибот-системы не полагаются на один сигнал — они комбинируют репутацию IP, HTTP-заголовки, TLS-отпечатки, браузерные отпечатки и поведенческий анализ для вычисления оценки риска. Когда она превышает порог, вы получаете блокировку, CAPTCHA или искажённые данные.
Это руководство описывает комплексный подход к снижению обнаружения на всех уровнях. Обзор работы этих систем — в нашей основной статье о том, как антибот-системы обнаруживают прокси.
Уровень 1: Репутация IP и выбор прокси
Ваш IP-адрес — первое, что видит сервер. Антибот-системы ведут базы данных, оценивающие IP по типу, истории и поведению.
Выбор типа прокси
| Тип прокси | Риск обнаружения | Лучше всего подходит для |
|---|---|---|
| Резидентные | Низкий | Большинство задач скрапинга, защищённые сайты |
| ISP (статические резидентные) | Низкий-Средний | Длительные сессии, аккаунты |
| Дата-центровые | Высокий | Незащищённые сайты, массовые задачи |
| Мобильные | Очень низкий | Максимально защищённые сайты, соцсети |
Для большинства проектов скрапинга резидентные прокси ProxyHat предлагают лучший баланс между низким риском обнаружения и экономичностью. Подробное сравнение типов прокси — в отдельной статье.
Стратегия ротации IP
# Python: ротация прокси на каждый запрос через ProxyHat
import requests
proxy_url = "http://USERNAME:PASSWORD@gate.proxyhat.com:8080"
proxies = {
"http": proxy_url,
"https": proxy_url
}
# Каждый запрос через шлюз получает другой IP
for url in urls_to_scrape:
response = requests.get(url, proxies=proxies, timeout=30)
process(response)
- Ротируйте на каждый запрос для страниц каталогов и поисковой выдачи.
- Используйте sticky-сессии для многостраничных потоков (пагинация, последовательности авторизации).
- Гео-таргетируйте IP под ожидаемую аудиторию сайта с помощью таргетинга по локациям ProxyHat.
Уровень 2: HTTP-заголовки
Некорректные или отсутствующие HTTP-заголовки — один из самых простых сигналов для антибот-систем. Реальный браузер отправляет 15-20 заголовков в определённом порядке; стандартный Python-скрипт — 3-4.
Необходимые заголовки
# Python: реалистичный набор заголовков
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8",
"Accept-Language": "en-US,en;q=0.9",
"Accept-Encoding": "gzip, deflate, br, zstd",
"Cache-Control": "max-age=0",
"Sec-Ch-Ua": '"Chromium";v="131", "Not_A Brand";v="24"',
"Sec-Ch-Ua-Mobile": "?0",
"Sec-Ch-Ua-Platform": '"Windows"',
"Sec-Fetch-Dest": "document",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-Site": "none",
"Sec-Fetch-User": "?1",
"Upgrade-Insecure-Requests": "1",
"Connection": "keep-alive"
}
response = requests.get(url, headers=headers, proxies=proxies)
Правила согласованности заголовков
- Согласуйте Sec-Ch-Ua с User-Agent: Если заявляете Chrome 131,
Sec-Ch-Uaдолжен ссылаться на версию 131. - Включайте все Sec-Fetch-заголовки: Современный Chrome отправляет их при каждой навигации. Их отсутствие — сильный бот-сигнал.
- Accept-Language должен соответствовать гео прокси: Прокси из США с
Accept-Language: ja-JPвыглядит подозрительно. - Поддерживайте порядок заголовков: Некоторые антибот-системы проверяют порядок. Используйте библиотеки, сохраняющие порядок вставки.
Уровень 3: TLS и HTTP/2 фингерпринтинг
Ваша HTTP-клиентская библиотека создаёт уникальный TLS-отпечаток, который антибот-системы сверяют с заявленным user-agent. User-agent Chrome с TLS-отпечатком Python мгновенно помечается.
Решения по языкам
| Язык | Стандартная библиотека | Риск обнаружения | Альтернатива браузерного уровня |
|---|---|---|---|
| Python | requests/urllib3 | Очень высокий | curl_cffi с impersonate |
| Node.js | axios/got | Высокий | got-scraping |
| Go | net/http | Очень высокий | uTLS + custom transport |
# Python: TLS браузерного уровня с curl_cffi
from curl_cffi import requests as curl_requests
response = curl_requests.get(
"https://example.com",
impersonate="chrome",
proxies={
"http": "http://USERNAME:PASSWORD@gate.proxyhat.com:8080",
"https": "http://USERNAME:PASSWORD@gate.proxyhat.com:8080"
}
)
Уровень 4: Браузерный фингерпринтинг
При использовании безголового браузера антибот-JavaScript проверяет ваш браузерный отпечаток — Canvas, WebGL, AudioContext, свойства navigator. Ключевой принцип — внутренняя согласованность:
- Все сигналы отпечатка должны согласовываться друг с другом
- Отпечаток должен соответствовать заявлениям user-agent
- Отпечаток должен меняться при ротации прокси
Стелс-конфигурация
// Node.js: Puppeteer со стелс-плагином и прокси
const puppeteer = require('puppeteer-extra');
const StealthPlugin = require('puppeteer-extra-plugin-stealth');
puppeteer.use(StealthPlugin());
const browser = await puppeteer.launch({
headless: 'new',
args: [
'--proxy-server=http://gate.proxyhat.com:8080',
'--disable-blink-features=AutomationControlled',
'--window-size=1920,1080'
]
});
const page = await browser.newPage();
await page.authenticate({
username: 'USERNAME',
password: 'PASSWORD'
});
await page.setViewport({ width: 1920, height: 1080 });
Уровень 5: Поведенческие паттерны
Даже при идеальной технической маскировке бот-подобные поведенческие паттерны вызовут обнаружение. Антибот-системы анализируют тайминг, паттерны навигации и сигнатуры взаимодействия.
Тайминг запросов
- Добавляйте случайные задержки: Люди не делают запросы через точные интервалы. Добавляйте 1-5 секунд случайной задержки между запросами.
- Варьируйте задержки по типу страницы: Страницы контента заслуживают более длинных пауз на «чтение», чем страницы каталогов.
- Избегайте всплесков: Не делайте 50 быстрых запросов с паузой. Распределяйте запросы равномерно с естественной вариацией.
# Python: естественный тайминг запросов
import time
import random
def scrape_with_natural_timing(urls, proxies):
for url in urls:
response = requests.get(url, proxies=proxies, headers=headers)
process(response)
# Случайная задержка: 1-4 секунды с нормальным распределением
delay = max(0.5, random.gauss(2.5, 0.8))
time.sleep(delay)
Паттерны навигации
- Следуйте естественным путям: Сначала посещайте главную, затем страницы категорий, затем детальные — не переходите сразу к глубоким URL.
- Устанавливайте корректные Referer-заголовки: Каждая страница должна ссылаться на предыдущую как referer.
- Обрабатывайте редиректы: Следуйте HTTP-редиректам естественно, а не повторяя запрос к исходному URL.
Управление сессиями
- Поддерживайте куки: Принимайте и возвращайте куки в рамках сессии — отброс всех куки является бот-сигналом.
- Ограничивайте длину сессии: После 50-100 запросов начинайте новую сессию со свежим IP и куки.
- Уважайте rate limits: При получении ответов 429 отступайте экспоненциально, а не повторяйте немедленно.
Уровень 6: Валидация ответов
Обнаружение не всегда приводит к блокировке. Сайты могут выдавать другой контент, подставлять ложные данные или возвращать мягкие блокировки. Всегда валидируйте ответы:
- Проверяйте коды статуса: 200 не всегда означает успех — некоторые сайты возвращают 200 с CAPTCHA-страницами или пустым контентом.
- Валидируйте структуру контента: Убедитесь, что ответ содержит ожидаемые элементы (цены, текст статей и т.д.).
- Следите за ловушками: Скрытые ссылки или поля форм, предназначенные для отлова автоматических краулеров.
- Отслеживайте процент успеха: Если он падает ниже 90%, что-то изменилось и требует расследования.
Комплексный чек-лист антидетекта
| Уровень | Действие | Приоритет |
|---|---|---|
| IP | Использовать резидентные прокси с гео-таргетингом | Критический |
| IP | Ротировать IP на каждый запрос или сессию | Критический |
| Заголовки | Отправлять полные, реалистичные наборы заголовков | Критический |
| Заголовки | Accept-Language соответствует локации прокси | Высокий |
| TLS | Использовать TLS-библиотеку браузерного уровня | Критический |
| TLS | TLS-отпечаток соответствует заявленному браузеру | Критический |
| Браузер | Стелс-плагины для безголовых браузеров | Высокий |
| Браузер | Согласованные профили отпечатков | Высокий |
| Поведение | Случайные задержки между запросами | Высокий |
| Поведение | Естественные пути навигации | Средний |
| Поведение | Поддержка куки в рамках сессий | Средний |
| Валидация | Проверка содержимого ответов, не только кодов статуса | Высокий |
Пример: полный антидетект-скрапер
# Python: полная настройка антидетект-скрапера
from curl_cffi import requests as curl_requests
import time
import random
class StealthScraper:
def __init__(self, proxy_user, proxy_pass):
self.proxy = f"http://{proxy_user}:{proxy_pass}@gate.proxyhat.com:8080"
self.session = curl_requests.Session(impersonate="chrome")
self.session.proxies = {
"http": self.proxy,
"https": self.proxy
}
self.request_count = 0
def get(self, url, referer=None):
headers = {}
if referer:
headers["Referer"] = referer
response = self.session.get(url, headers=headers, timeout=30)
self.request_count += 1
# Ротация сессии каждые 50-80 запросов
if self.request_count >= random.randint(50, 80):
self._rotate_session()
# Естественная задержка
time.sleep(max(0.5, random.gauss(2.0, 0.6)))
return response
def _rotate_session(self):
self.session = curl_requests.Session(impersonate="chrome")
self.session.proxies = {
"http": self.proxy,
"https": self.proxy
}
self.request_count = 0
# Использование
scraper = StealthScraper("USERNAME", "PASSWORD")
home = scraper.get("https://example.com")
listing = scraper.get("https://example.com/products", referer="https://example.com")
detail = scraper.get("https://example.com/products/123", referer="https://example.com/products")
Когда усиливать подход
Начинайте с простейшего подхода и усиливайте только при необходимости:
- Уровень 1 — HTTP-клиент + заголовки + прокси: Работает для большинства сайтов. Используйте
curl_cffiилиgot-scrapingс прокси ProxyHat. - Уровень 2 — Добавить TLS браузерного уровня: Требуется, когда сайт проверяет отпечатки JA3/JA4.
- Уровень 3 — Безголовый браузер + стелс: Необходимо для JavaScript-контента и сложных антибот-систем.
- Уровень 4 — Полная автоматизация браузера с поведенческой мимикрией: Для самых защищённых сайтов (Cloudflare Enterprise, PerimeterX и др.).
Паттерны реализации для конкретных языков — в наших руководствах: Python, Node.js и Go.
Этические рекомендации
Техники антидетекта — это инструменты, этичность которых зависит от контекста. Всегда:
- Уважайте robots.txt и условия использования
- Собирайте только публично доступные данные
- Ограничивайте частоту запросов для минимизации нагрузки на серверы
- Соблюдайте нормативные акты о защите данных (GDPR, CCPA)
- Используйте этичные практики скрапинга как базу
Цель антидетекта — не обход легитимной безопасности, а обеспечение того, чтобы ваш автоматизированный доступ к публичным данным не был ошибочно помечен как вредоносный.






