Стабильная работа парсера - это не про хакерские трюки, а про банальную выживаемость скрипта дольше одного дня. Я веду парсеры для мониторинга цен конкурентов, сбора остатков у поставщиков и трекинга статусов СДЭК уже несколько лет, и почти каждый проект на старте спотыкается об одно и то же: через 15-40 минут работы IP улетает в бан, а следом заголовки запроса с порога выдают, что это не браузер живого человека, а requests или Playwright с настройками по умолчанию. Дальше - рабочая связка приёмов, которую я реально гоняю в продакшн-скриптах: ротация прокси, подмена User-Agent и заголовков, борьба с фингерпринтингом браузера и поведенческие тайминги, которые снижают долю банов до единиц процентов.
Почему парсеры банят: IP, User-Agent и фингерпринт браузера
Антифрод-система сайта смотрит на запрос слоями, и банит не за одну ошибку, а за совпадение сразу нескольких сигналов. Первый слой - частота запросов с одного IP: у большинства интернет-магазинов на WooCommerce и Tilda-сайтов с подключёнными скриптами защиты (Cloudflare, Qrator) лимит стоит на уровне 40-80 запросов в минуту с адреса, дальше идёт капча или временный бан на 15-60 минут. Второй слой - заголовки: дефолтный User-Agent от requests или python-httpx палится мгновенно, потому что реальный Chrome шлёт ещё десяток сопутствующих заголовков (sec-ch-ua, sec-fetch-mode, порядок заголовков тоже имеет значение). Третий слой - TLS-фингерпринт, он же JA3: даже если User-Agent подделан правильно, TLS-рукопожатие библиотеки requests отличается от рукопожатия настоящего Chrome, и сервер видит это ещё до того, как прочитает тело запроса. Четвёртый слой - фингерпринт браузера через JS: canvas, WebGL, список шрифтов, размер экрана, часовой пояс. Headless Chrome без доп. настроек светит это одной строкой в navigator.webdriver.
На практике бан редко случается из-за одного фактора - обычно система копит баллы риска, и превышение порога включает капчу или блокировку. Поэтому устойчивость к банам работает только как связка мер, а не как один волшебный флаг.
Ротация прокси - как не собрать бан по IP
Первое, с чего я начинаю любой парсер, который ходит больше сотни раз в час, - прокси-пул с ротацией. Голый список из 5-10 датацентровых IP закрывает вопрос на день-два, потом сайт вычисляет всю подсеть провайдера и банит её целиком - так было с парсингом остатков у одного поставщика на WooCommerce, где после недели работы в бан улетел весь диапазон OVH.
Прокси делю на три типа и выбираю по задаче:
| Тип прокси | Цена (рынок) | Риск бана | Когда брать |
|---|---|---|---|
| Датацентровые | 100-300 ₽/шт в месяц | Высокий на защищённых сайтах | Простые сайты без Cloudflare, внутренние API |
| Residential | от 300-500 ₽/GB | Низкий | Магазины, агрегаторы, соцсети |
| Мобильные | от 1000-2000 ₽/GB | Минимальный | Жёсткий антифрод, маркетплейсы, соцсети |
Цены в таблице - рыночный ориентир по провайдерам прокси, не мои расценки на разработку. Для мониторинга цен на WooCommerce обычно хватает residential-пула на 5-10 GB в месяц с ротацией IP каждые 5-10 запросов - этого достаточно, чтобы не собирать подсеть в бан-лист. Для СДЭК-трекинга через личный кабинет ротацию делаю реже, раз в 20-30 запросов, потому что там важнее не частота смены IP, а стабильность сессии - слишком частая смена адреса при активной cookie-сессии сама по себе триггерит проверку.
Ротацию завязываю на прокси-провайдера с sticky-сессиями (IP держится 5-10 минут на одном запросе-цепочке) - это ближе к поведению живого пользователя, чем смена IP на каждый запрос, которая наоборот выглядит подозрительно.
Подмена User-Agent и заголовков запроса
User-Agent меняю не рандомным генератором из интернета (там до сих пор попадаются строки для Chrome 44), а списком актуальных строк реальных браузеров - беру свежие версии Chrome, Firefox, Safari под Windows/Mac/Android и обновляю список раз в месяц-два, синхронно с реальными релизами браузеров.
Отдельно слежу, чтобы весь набор заголовков соответствовал заявленному User-Agent: если строка говорит про Chrome 126 на Windows, а sec-ch-ua-platform тем временем шлёт Linux - это расхождение антифрод ловит за секунды. Для requests-запросов без полноценного браузера использую curl_cffi - библиотека имитирует не только заголовки, но и TLS-отпечаток конкретной версии Chrome или Firefox, чего обычный requests с подменённым User-Agent сделать не может в принципе.
Порядок заголовков тоже важен: браузеры шлют их в фиксированной последовательности, а самописный клиент часто расставляет как попало. Мелочь, но на сайтах с жёстким антифродом именно такие детали и решают, пройдёт запрос как «человеческий» или нет.
Бесплатный материал
🎁 Полезный скрипт в подарок
Подпишитесь на Telegram - пришлю готовый скрипт по этой теме.
Без спама. Отписка в 1 клик.
Браузерная автоматизация и фингерпринтинг: на что смотрит защита
Когда сайт рендерит контент через JS и без браузера не обойтись, встаёт вопрос фингерпринтинга: canvas, WebGL, аудио-контекст, список плагинов, часовой пояс, разрешение экрана - из этого антифрод-система собирает уникальный отпечаток устройства, который держится даже при смене IP и User-Agent.
Для Playwright/Selenium использую готовые библиотеки, которые снижают вероятность детекции автоматизации браузера, - они меняют типовые технические признаки headless-режима. Для задач посерьёзнее - коммерческие браузеры с изоляцией профилей:
| Инструмент | Профили | API для автоматизации | Подходит для |
|---|---|---|---|
| Multilogin | Неограниченно (платно) | Есть | Крупные проекты с большим числом профилей |
| GoLogin | По тарифу | Есть | Средние объёмы, соцсети |
| AdsPower | По тарифу | Есть | Бюджетный вариант для старта |
| undetected-chromedriver | Без ограничений (бесплатно) | Через Selenium | Единичные скрипты на Python |
В 80% моих проектов до коммерческих браузеров с изоляцией профилей дело не доходит - хватает undetected-chromedriver или curl_cffi плюс грамотная ротация прокси. Полноценный браузер с изолированными профилями беру, только когда нужно держать десятки параллельных сессий под разными «личностями» одновременно, например при парсинге соцсетей или маркетплейсов с персонализированной выдачей.
Поведенческие паттерны и тайминги без резких движений
Самый частый провал у новичков - идеально ровные интервалы между запросами. Запрос каждые ровно 2 секунды 24 часа подряд не делает ни один живой человек, и это видно по логам сразу. Задержки ставлю случайные, с разбросом (например, 1.5-4.5 секунды с нормальным распределением, а не равномерным), плюс раз в 20-40 запросов делаю паузу подольше, как будто пользователь отвлёкся.
Для браузерной автоматизации добавляю имитацию движения мыши перед кликом (не телепорт курсора в точку клика, а несколько промежуточных точек), скролл страницы перед парсингом видимого контента, случайные микро-паузы между вводом символов в поля форм. На капчу это тоже влияет: чем более рвано ведёт себя автоматизация, тем выше шанс, что система защиты от ботов покажет дополнительную проверку.
Паралелльность тоже держу под контролем - не запускаю 50 потоков на один домен одновременно, даже с разными прокси, потому что резкий скачок трафика на сайт сам по себе аномалия. Обычно ограничиваюсь 3-5 параллельными сессиями на источник и наращиваю нагрузку постепенно, а не рывком с первой минуты.
Как я подбираю связку инструментов под конкретный источник
На практике связка зависит от источника. Мониторинг цен конкурентов на WooCommerce обычно закрываю requests + curl_cffi + residential-прокси с ротацией - сайт без сложного антифрода, JS-рендер не нужен, бан случается редко даже без браузерной эмуляции. Трекинг статусов доставки СДЭК через API или личный кабинет требует более аккуратной работы с сессией и cookie, там важнее не спалить фингерпринт при повторных заходах, чем менять IP на каждый запрос.
Для бота на aiogram, который раз в час подтягивает данные с внешнего сайта и шлёт уведомление в Telegram, дополнительная маскировка запросов обычно избыточна по полной программе - хватает обычного User-Agent и одного стабильного residential-прокси, потому что частота запросов низкая и подозрений не вызывает. А вот когда парсинг встраивают в цепочку n8n с десятками срабатываний в день, ротацию прокси и заголовков продумываю заранее, иначе воркфлоу через неделю начинает падать с ошибками 403 без объяснения причины.
Готовые заготовки под типовые случаи - ротация прокси, работа с JS-рендерингом, эмуляция браузера - у меня собраны в библиотеке готовых скриптов для парсинга, оттуда беру основу и адаптирую под конкретный сайт вместо написания с нуля. Если источник закрыт от парсинга несколькими уровнями защиты, разработка устойчивого парсера под такой сайт у меня стартует от 20 000 ₽ - конкретная цифра зависит от сложности источника и объёма данных.
Данные и процессы на автопилоте
Парсинг / Автоматизация
от 20 000 ₽
Подробнее →Частые вопросы
Нужна ли специальная настройка парсера для небольшого сайта, если он опрашивается раз в день?
Нет, для редких единичных запросов достаточно обычного User-Agent и одного стабильного прокси. Расширенная настройка с ротацией и эмуляцией браузера имеет смысл, только если запросов много и сайт защищён серьёзной антибот-системой.
Чем residential прокси лучше datacenter для парсинга?
Residential-адрес выдан реальному провайдеру домашнего интернета, и антифрод-системы доверяют такому IP как обычному пользователю. Датацентровые адреса легко вычисляются по принадлежности подсети хостинг-провайдеру и банятся пачками, особенно на сайтах с Cloudflare.
Как проверить, что мой парсер не палится по фингерпринту?
Есть открытые сервисы проверки фингерпринта браузера (например, показывающие данные canvas, WebGL, TLS JA3) - запускаю через них тот же браузерный профиль, что использую в парсере, и смотрю, не выдаёт ли он navigator.webdriver: true или явно ботовский TLS-отпечаток.
Что делать, если сайт всё равно показывает капчу?
Чаще всего дело в таймингах (слишком ровные интервалы между запросами) или параллельности (много потоков с одного источника одновременно) - это выглядит подозрительно для любой системы защиты. Снижаю частоту запросов, увеличиваю разброс задержек и проверяю, не совпадает ли технический профиль у нескольких параллельных сессий.