Вход Регистрация

Кейсы

Как обойти WAF при скрапинге: этичный гайд

WAF защищает сайты и веб-приложения от атак на уязвимости. Он может определять автоматический трафик как при скрапинге. Как обойти WAF и не нарушить этику?

Команда Froxy 19 ноя 2025 5 мин
Как обойти WAF при скрапинге: этичный гайд

Разработчики парсеров давно заметили, что наиболее сложные системы защиты целевых сайтов научились определять автоматический трафик, даже если скрипт использует headless-браузеры и веб-драйверы. Частичным решением стали готовые реализации stealth-плагинов и библиотек типа nodriver. Ниже постараемся в деталях разобраться с тем, как и на основе чего выявляются и блокируются автоматические запросы, а также в том, как обойти WAF без готовых решений.

Что такое брандмауэр веб-приложений (WAF)?

Брандмауэр веб-приложений (Web Application Firewall или WAF) — это программный комплекс, который защищает сайты и веб-приложения от атак, направленных на уязвимости в их коде, архитектуре или логике работы. В отличие от классического сетевого брандмауэра, который фильтрует трафик по IP-адресам, портам и протоколам, WAF анализирует HTTP(S)-запросы и ответы максимально глубоко, фактически отслеживая то, что происходит на уровне приложений (на прикладном уровне по модели OSI).

WAF позволяет обнаружить и предотвратить попытки эксплуатации уязвимостей, таких как:

  • SQL-инъекции;
  • XSS (межсайтовый скриптинг);
  • атаки с подменой cookie или сессий;
  • внедрение вредоносных команд через формы и API-запросы;
  • попытки обхода механизмов аутентификации.

WAF может взять на себя не только мониторинг (когда софт просто фиксирует подозрительные запросы), но и активную блокировку (когда брандмауэр останавливает вредоносный трафик). Многие продвинутые WAF-комплексы умеют обучаться в процессе работы — они анализируют поведение пользователей и статистику запросов для более тонкой настройки правил защиты.

Современные решения WAF часто внедряются в составе систем облачной безопасности или CDN-платформ (например, как в случае с Cloudflare), интегрируются с SIEM-системами (Security Information and Event Management), а также используют искусственный интеллект и машинное обучение для выявления аномалий.

Но нам в контексте статьи более интересно применение WAF при борьбе со скрапингом. А если ещё точнее — как обойти WAF при парсинге.

Почему и как WAF блокирует веб-скрапинг

Почему и как WAF блокирует веб-скрапинг

Во-первых, многие сайты и веб-приложения намеренно блокируют ботов и любой автоматический трафик, который создаёт паразитную нагрузку. Никому не хочется переплачивать за хостинг. Да и при определённой нагрузке сайт может замедлить свою работу, соответственно, реальным «живым» клиентам пользоваться им станет невозможно — примерно, как при DDoS-атаках.

Во-вторых, WAF анализирует подозрительные действия со стороны клиентов и может ошибочно определить запросы от парсеров как вредоносные или опасные для сайта. Например, если запросы с одного IP-адреса слишком частые или бот пытается заполнить формы-ловушки.

В-третьих, автоматические запросы и парсинг могут противоречить правилам использования ресурса, а контент может быть защищен авторскими правами, соответственно, владельцы сайта могут предпринимать свои превентивные технические меры по его защите от считывания.

По каким именно признакам брандмауэр веб-приложений может определять парсеров и ботов:

  • Aнализ сигнатур (специальных технических признаков и заголовков ботов, парсеров и headless-браузеров) — по аналогии с цифровыми отпечатками;
  • Поведенческий анализ (он наиболее ресурсоёмкий, поэтому задействуется редко либо проводится по простейшим паттернам и правилам);
  • Проверка «человечности» за счёт капчи и выполнения специальных JS-скриптов на стороне клиента;
  • Анализ IP-адресов (репутация + расположение и тип).

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

Этические соображения при обходе брандмауэра

Этические соображения при обходе брандмауэра веб-приложений связаны с балансом между безопасностью, конфиденциальностью, свободой доступа и ответственностью за обработку данных пользователей/сайта (если они защищены авторскими правами). Ключевые аспекты:

  • Разработчики парсеров должны учитывать, что WAF защищает сайт не только технически, но и юридически. Игнорирование фильтров, попытки обхода капчи или подмены заголовков могут нарушать правила использования ресурса и трактоваться как вмешательство в работу системы.
  • WAF-байпас должен предпочитать работу через официальный API-интерфейс, если он имеется для партнёров сайта или сервиса.
  • Не стоит создавать слишком сильную нагрузку на хостинг, отправляя одновременно большое количество запросов. Так вы можете нарушить работу сервиса.
  • Нужно чётко отделять контент, хранение которого может нарушать чьи-то авторские права или нарушать конфиденциальность (речь уже о персональных данных пользователей).

Соблюдение этих правил позволит вам оставаться в нормальном правовом и этическом поле, не провоцируя блокировки и не нарушая баланс интересов между владельцем сайта и конечными пользователями.

Методы обхода WAF при веб-скрапинге с примерами кода

Методы обхода WAF при веб-скрапинге с примерами кода

Что такое обход WAF (WAF-байпас) — это попытка обойти фильтры и алгоритмы блокировки брандмауэра веб-приложений, чтобы получить доступ к содержимому сайта или веб-сервиса в целях автоматизации действий, парсинга или для реализации других задач.

Чтобы обойти защиту WAF, достаточно знать и учитывать основные методы обнаружения автоматического трафика. Мы перечислили их выше. Например, если WAF блокирует серверные IP, нужно использовать резидентные или мобильные прокси, если анализирует куки, сохраняет токены сессий и проверяет наличие исполнения JavaScript, то логично организовать работу через headless-браузеры. Если детально изучает цифровые отпечатки и следы автоматизации, то можно задействовать систему реалистичных браузерных профилей в связке с антидетект-браузерами и т.п.

Ниже разберём ряд технических приёмов для конкретных узких задач парсинга.

Смена пользовательских агентов и заголовков

Значение заголовка с user-агентом должно быть реалистичным и в идеале должно соответствовать актуальным версиям популярных браузеров. Не менее важно подумать о естественности других заголовков: локаль, кодировка и т.п.

Пример случайных заголовков на Python:


import random
user_agents = [
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36',
    'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36',
    ' Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36'
]
headers = {
    'User-Agent': random.choice(user_agents), # Здесь выбирается случайный юзер-агент из списка выше
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', # показываем какие медиа-типы (форматы содержимого) браузер предпочитает получать в ответ и с каким приоритетом/качеством
    'Accept-Language': 'en-US,en;q=0.5', # Предпочитаемый язык
    'Accept-Encoding': 'gzip, deflate', # Предпочитаемые варианты сжатия
    'Referer': 'https://www.google.com/' # Кто выступил в роли источника перехода
}

Если вы подключаетесь через headless-браузеры, то нужно подумать ещё и об отключении определённым атрибутов, а также о более «естественных» настройках контекста: размер окна браузера, используемые шрифты и т.п. Пример указания таких настроек смотрите ниже — в блоке с ротацией прокси.

Использование резидентных и ротационных прокси

Если у вас разрозненные списки прокси, то их нужно ротировать своими силами. Например, так:


import requests
import random
proxies_list = [
    'http://user:pass@192.168.1.1:8080',
    'http://user:pass@192.168.1.2:8080',
    'http://user:pass@192.168.1.3:8080'
]
proxy = {'http': random.choice(proxies_list), 'https': random.choice(proxies_list)}
response = requests.get('https://example.com', proxies=proxy, timeout=10) # Тут таймаут фиксированный, но так лучше не делать, код просто для примера и понимания

Но если вы задействуете сервис ротируемых прокси, такой как Froxy, то прокси в коде могут подключаться всего один раз, а дальнейшая ротация и правила подбора настраиваются в личном кабинете сервиса или по API.

Пример для подключения парсера через прокси с использованием headless-браузера и «человеческих» атрибутов без задействования Stealth-плагинов (работаем через веб-драйвер Playwright):


from playwright.sync_api import sync_playwright

def create_browser_with_residential_proxy():
    with sync_playwright() as p:
        # Конфигурация резидентного прокси
        proxy_config = {
            'server': 'http://proxy.froxy.com:9000',  # или socks5:// для SOCKS5
            'username': 'your_login',
            'password': 'your_password'
        }
        
        # Запуск браузера с прокси
        browser = p.chromium.launch(
            headless=True,
            proxy=proxy_config,  # передаём конфигурацию прокси
            args=[
                # Скрываем атрибуты автоматизации
                '--disable-blink-features=AutomationControlled',
                '--no-sandbox',
                '--disable-dev-shm-usage'
            ]
        )
        
        # Создание контекста с дополнительными настройками
        context = browser.new_context(
            viewport={'width': 1920, 'height': 1080}, # Реалистичное разрешение экрана
            user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36' # Реалистичный юзер-агент
        )
        
        # Дополнительное скрытие признаков работы через веб-драйвер на уровне JS-кода на этапе инициализации браузера
        page = context.new_page()
        page.add_init_script("""
            Object.defineProperty(navigator, 'webdriver', {
                get: () => undefined,
            });
        """)
        
        return browser, page

# Использование
browser, page = create_browser_with_residential_proxy()

try:
    # Переход на целевой сайт через прокси
    page.goto('https://target-site.org/page1', timeout=60000)
    # Дальнейшие действия скрапинга...
    # data = page.locator('.content').text_content()
    
finally:
    # Закрытие браузера
    browser.close()

Правильное (естественное) управление файлами cookie и сеансами

Скрипт обхода WAF должен уметь сохранять и повторно использовать cookies для имитации реальной пользовательской сессии.

Пример на Python + Requests (подробнее о библиотеке Requests):


import requests
session = requests.Session()
# Первый запрос для получения cookies
session.get('https://example.com/login')
# Последующие запросы используют те же cookies
response = session.get('https://example.com/protected-page')
# Ручная установка cookies
session.cookies.update({'session_id': 'abc123', 'user_prefs': 'en'})

Headless-браузеры автоматически сохраняют куки в рамках одной сессии. Хотя вы можете настроить кастомную логику работы с ними и ручное добавление кук.

Добавление задержек и рандомизации

Человек никогда не выдерживает между своими действиями одинаковых интервалов. Поэтому элемент случайности в задержках между запросами крайне важен. Мы рекомендуем устанавливать лимиты времени — от … и до …, чтобы не получить слишком больших и слишком маленьких задержек.


import time
import random
def human_delay(min_delay=1, max_delay=5):
    # Случайная задержка между запросами
    time.sleep(random.uniform(min_delay, max_delay))
# Использование в цикле скрапинга
for page in range(10):
    human_delay(2, 7)  # Пауза от 2 до 7 секунд
    # ... выполнение запроса

Скрытие атрибутов headless-браузеров (без стелс-библиотек)

Вариант маскировки признаков автоматизированного браузера через настройки Selenium (Python):


from selenium import webdriver
from selenium.webdriver.chrome.options import Options

options = Options()
options.add_argument("--disable-blink-features=AutomationControlled")
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option('useAutomationExtension', False)
options.add_argument('--disable-dev-shm-usage')
options.add_argument('--no-sandbox')

driver = webdriver.Chrome(options=options)

# Скрытие признаков веб-драйвера на уровне JS-кода
driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: () => undefined})")

# Установка нормального user-agent
options.add_argument("--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36")

Как избежать подозрительных шаблонов запросов — дополнительные стратегии

Обозначим остальные подходы для обхода WAF, чтобы вы знали какие реализации и для чего можно использовать:

  • Случайный фактор в последовательности действий, особенно в списке страниц на обход.
  • Эмуляция человеческого поведения в браузере — шевеление курсором, естественный скроллинг страниц, случайные клики по элементам страницы, посимвольный ввод текста в формах и т.п.
  • Интеграция с сервисами для решения капчи.
  • Подбор естественных прокси — на базе адресов домашних или мобильных пользователей из разных подсетей и регионов — чтобы все прокси не были из одного кластера при частых обращениях, так как это очень сильно напоминает DDoS. Но вместе с тем, в некоторых случаях логично удерживать сессию максимально долго, а при ротации подбирать адреса в той же подсети или у того же оператора связи. Такой реконнект будет выглядеть весьма естественно, так как у многих ISP динамическая ротация IP-адресов.
  • Проверка страниц и ответов сервера на наличие ошибок. Если сервер сообщает о превышении количества подключений, то достаточно уменьшить нагрузку и выждать немного времени. А если это ошибки доступа, свидетельствующие о блокировке, то пора ротировать IP и цифровой отпечаток.
  • Исключение страниц для обхода на основе правил, которые сформулированы в robots.txt.
  • Отключение WebRTC в настройках headless-браузера, а также генерация правдоподобных потоков на аудиоустройствах и веб-камере.
  • Предварительное наполнение кук — можно организовать за счёт последовательного посещения случайного набора сайтов в сети (чтобы куки не были пустыми).
  • Задействование кеширования картинок и статических файлов — чтобы исключить массовую повторную загрузку (тоже явный признак автоматизации).

Если вы знакомы с ИИ, то можно организовать полноценный пайплайн с привлечением LLM. Так вы сможете генерировать более естественное поведение и паттерны, а также цифровые отпечатки, которые сложно описать на уровне случайных значений и простого кода.

Пример скрапинга вместе с Chat GPT, а также материал о применении фреймворков LangChain и LangGraph.

Заключение и рекомендации

способы обхода WAF

Как мы неоднократно уже говорили, сайты и механизмы их защиты становятся с каждым годом всё сложнее. Но в эту игру можно играть вдвоём: механизмы и способы обхода WAF (Web Application Firewall) тоже совершенствуются и не стоят на месте. При желании можно эмулировать абсолютно всё — от цифровых отпечатков и поведения пользователя до расположения клиента и аудиопотока с микрофона. Это как танцевать танго, двигаясь синхронно с партнёром.

Мы предоставляем качественные ротируемые прокси с точным таргетингом до конкретного населённого пункта и ISP-провайдера по всему миру, а также набор готовых облачных парсеров, работающих по API.

Получайте уведомления о новых функциях и обновлениях Froxy

Узнайте первыми о новых функциях Froxy, чтобы оставаться в курсе событий происходящих на рынке цифровых технологий и получать новости о новых функциях Froxy.

Статьи по Теме

Как библиотека chromedp помогает с парсингом

Парсинг

Как библиотека chromedp помогает с парсингом

Узнайте больше о chromedp и о том, как вы можете использовать его для скрапинга. Мы приведем примеры и наиболее актуальные сценарии использования.

Команда Froxy 12 сен 2024 14 мин
Почему без прокси вы тратите больше, чем думаете

Прокси

Почему без прокси вы тратите больше, чем думаете

Узнайте, как отсутствие прокси-серверов увеличивает затраты: от блокировок и потерь в скрапинге до неэффективной автоматизации. Примеры и решения...

Команда Froxy 4 июн 2025 5 мин