Назад к блогу

Как обойти детекцию Cloudflare при использовании прокси

Cloudflare блокирует ваши запросы через прокси? Разбираем технические методы обхода детекции: от правильной настройки TLS до использования headless-браузеров с реальными примерами.

📅17 декабря 2025 г.

7 проверенных способов обойти детекцию Cloudflare при работе через прокси

Cloudflare обрабатывает более 20% всего веб-трафика и использует многоуровневую систему защиты от ботов. При работе через прокси-серверы вероятность получить капчу или блокировку возрастает в разы. В этом руководстве разберём технические аспекты детекции и практические методы обхода, которые работают в 2024 году.

Как Cloudflare определяет прокси и ботов

Cloudflare использует комплексную систему анализа, которая проверяет десятки параметров каждого запроса. Понимание механизмов детекции — первый шаг к успешному обходу защиты.

Основные методы детекции

TLS Fingerprinting: Cloudflare анализирует параметры SSL/TLS-рукопожатия (cipher suites, расширения, порядок их следования). Каждый HTTP-клиент имеет уникальный "отпечаток". Например, Python requests использует OpenSSL с характерным набором шифров, который легко отличить от Chrome или Firefox.

При анализе запроса Cloudflare сопоставляет TLS fingerprint с заявленным User-Agent. Если вы указываете Chrome 120, но TLS-параметры соответствуют Python requests — это моментальная детекция бота.

Параметр проверки Что анализируется Риск детекции
TLS fingerprint Cipher suites, расширения, версия TLS Высокий
HTTP/2 fingerprint Порядок заголовков, SETTINGS фреймы Высокий
IP-репутация История IP, принадлежность к дата-центрам Средний
JavaScript challenge Выполнение JS, canvas fingerprint, WebGL Высокий
Поведенческий анализ Паттерны запросов, timing, mouse movements Средний

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

Маскировка TLS fingerprint

TLS fingerprinting — наиболее эффективный метод детекции ботов. Стандартные HTTP-клиенты (requests, curl, axios) создают fingerprint, который невозможно спутать с реальным браузером. Решение — использование специализированных библиотек, имитирующих TLS-поведение браузеров.

Использование curl-impersonate

Библиотека curl-impersonate — модифицированная версия curl, которая точно копирует TLS и HTTP/2 fingerprints популярных браузеров. Поддерживает Chrome, Firefox, Safari и Edge.

# Установка curl-impersonate
git clone https://github.com/lwthiker/curl-impersonate
cd curl-impersonate
make chrome-build

# Использование с имитацией Chrome 120
curl_chrome120 -x http://username:password@proxy.example.com:8080 \
  -H "Accept-Language: en-US,en;q=0.9" \
  https://example.com

Python: библиотека tls-client

Для Python существует обёртка tls-client, которая использует curl-impersonate под капотом и предоставляет интерфейс, похожий на requests.

import tls_client

# Создание сессии с fingerprint Chrome 120
session = tls_client.Session(
    client_identifier="chrome_120",
    random_tls_extension_order=True
)

# Настройка прокси
proxies = {
    'http': 'http://username:password@proxy.example.com:8080',
    'https': 'http://username:password@proxy.example.com:8080'
}

# Выполнение запроса
response = session.get(
    'https://example.com',
    proxies=proxies,
    headers={
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
        'Accept-Language': 'en-US,en;q=0.9',
        'Accept-Encoding': 'gzip, deflate, br',
        'DNT': '1',
        'Connection': 'keep-alive',
        'Upgrade-Insecure-Requests': '1'
    }
)

print(response.status_code)

Важно: При использовании tls-client критически важно, чтобы User-Agent в заголовках соответствовал выбранному client_identifier. Несоответствие приведёт к немедленной детекции.

Проверка TLS fingerprint

Перед началом парсинга рекомендуется проверить ваш TLS fingerprint. Используйте сервисы tls.peet.ws или ja3er.com для анализа.

# Проверка fingerprint
response = session.get('https://tls.peet.ws/api/all')
print(response.json()['tls']['ja3'])

# Сравните с fingerprint реального Chrome:
# https://kawayiyi.com/tls-fingerprint-database/

Правильная настройка HTTP-заголовков

Даже с правильным TLS fingerprint неверные HTTP-заголовки выдадут бота. Cloudflare анализирует не только наличие заголовков, но и их порядок, формат значений и логическую согласованность.

Обязательные заголовки для Chrome

headers = {
    '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',
    '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',
    'DNT': '1',
    'Connection': 'keep-alive',
    'Upgrade-Insecure-Requests': '1',
    'Sec-Fetch-Dest': 'document',
    'Sec-Fetch-Mode': 'navigate',
    'Sec-Fetch-Site': 'none',
    'Sec-Fetch-User': '?1',
    'Sec-Ch-Ua': '"Not_A Brand";v="8", "Chromium";v="120", "Google Chrome";v="120"',
    'Sec-Ch-Ua-Mobile': '?0',
    'Sec-Ch-Ua-Platform': '"Windows"',
    'Cache-Control': 'max-age=0'
}

Заголовки Sec-Ch-Ua-* появились в Chrome 89 и являются частью Client Hints API. Их отсутствие при использовании современного User-Agent — явный признак бота.

Порядок заголовков имеет значение

В HTTP/2 порядок заголовков фиксирован для каждого браузера. Python requests и другие стандартные клиенты отправляют заголовки в алфавитном порядке, что отличается от поведения браузеров. Используйте библиотеки с поддержкой кастомного порядка заголовков.

Совет: Используйте DevTools браузера (Network tab → правый клик на запросе → Copy → Copy as cURL) для получения точной копии заголовков реального браузера. Затем адаптируйте их под свой код.

Динамическая генерация User-Agent

Использование одного и того же User-Agent для всех запросов увеличивает риск детекции. Создавайте пул актуальных User-Agent и ротируйте их.

import random

# Пул актуальных User-Agent (декабрь 2024)
USER_AGENTS = [
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
    'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0',
    'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.1 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'
]

def get_random_headers():
    ua = random.choice(USER_AGENTS)
    
    # Адаптация других заголовков под выбранный UA
    if 'Chrome' in ua:
        return {
            'User-Agent': ua,
            'Sec-Ch-Ua': '"Not_A Brand";v="8", "Chromium";v="120"',
            # ... остальные заголовки Chrome
        }
    elif 'Firefox' in ua:
        return {
            'User-Agent': ua,
            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
            # ... заголовки Firefox
        }
    # ... обработка других браузеров

Использование headless-браузеров

Когда Cloudflare использует JavaScript challenge или продвинутую детекцию, единственный надёжный способ обхода — реальный браузер. Headless-браузеры автоматически обрабатывают JavaScript, cookies и создают полностью аутентичный fingerprint.

Playwright с anti-detect патчами

Playwright — современная альтернатива Selenium с лучшей производительностью. Однако стандартный Playwright легко детектируется через navigator.webdriver и другие маркеры. Используйте playwright-stealth для маскировки.

from playwright.sync_api import sync_playwright
from playwright_stealth import stealth_sync

def bypass_cloudflare(url, proxy):
    with sync_playwright() as p:
        browser = p.chromium.launch(
            headless=True,
            proxy={
                "server": f"http://{proxy['host']}:{proxy['port']}",
                "username": proxy['username'],
                "password": proxy['password']
            },
            args=[
                '--disable-blink-features=AutomationControlled',
                '--disable-dev-shm-usage',
                '--no-sandbox'
            ]
        )
        
        context = browser.new_context(
            viewport={'width': 1920, 'height': 1080},
            user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
            locale='en-US',
            timezone_id='America/New_York'
        )
        
        page = context.new_page()
        stealth_sync(page)  # Применение anti-detect патчей
        
        # Переход на страницу
        page.goto(url, wait_until='networkidle', timeout=30000)
        
        # Ожидание прохождения Cloudflare challenge (обычно 5-10 секунд)
        page.wait_for_timeout(8000)
        
        # Проверка успешного обхода
        if 'Just a moment' in page.content():
            print('Cloudflare challenge не пройден')
            return None
        
        # Извлечение cookies для дальнейшего использования
        cookies = context.cookies()
        html = page.content()
        
        browser.close()
        return {'html': html, 'cookies': cookies}

# Использование
proxy_config = {
    'host': 'proxy.example.com',
    'port': 8080,
    'username': 'user',
    'password': 'pass'
}

result = bypass_cloudflare('https://example.com', proxy_config)

Puppeteer Extra с плагинами

Для Node.js экосистемы лучшим решением является puppeteer-extra с плагином puppeteer-extra-plugin-stealth. Этот плагин применяет более 30 различных техник маскировки автоматизации.

const puppeteer = require('puppeteer-extra');
const StealthPlugin = require('puppeteer-extra-plugin-stealth');

puppeteer.use(StealthPlugin());

async function bypassCloudflare(url, proxyUrl) {
    const browser = await puppeteer.launch({
        headless: 'new',
        args: [
            `--proxy-server=${proxyUrl}`,
            '--disable-blink-features=AutomationControlled',
            '--window-size=1920,1080'
        ]
    });
    
    const page = await browser.newPage();
    
    // Установка viewport и user-agent
    await page.setViewport({ width: 1920, height: 1080 });
    await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36');
    
    // Переопределение navigator.webdriver
    await page.evaluateOnNewDocument(() => {
        delete Object.getPrototypeOf(navigator).webdriver;
    });
    
    // Переход на страницу
    await page.goto(url, { waitUntil: 'networkidle2', timeout: 30000 });
    
    // Ожидание прохождения challenge
    await page.waitForTimeout(8000);
    
    // Получение контента и cookies
    const content = await page.content();
    const cookies = await page.cookies();
    
    await browser.close();
    
    return { content, cookies };
}

// Пример использования
bypassCloudflare('https://example.com', 'http://user:pass@proxy.example.com:8080')
    .then(result => console.log('Success'))
    .catch(err => console.error(err));

Производительность: Headless-браузеры потребляют значительно больше ресурсов (200-500 МБ RAM на инстанс). Для высоконагруженных задач используйте их только для получения cookies, затем переключайтесь на HTTP-клиенты с этими cookies.

Выбор типа прокси для обхода Cloudflare

Тип прокси критически влияет на успешность обхода. Cloudflare ведёт базы IP-адресов дата-центров и применяет к ним более строгие правила проверки.

Тип прокси Вероятность обхода Скорость Стоимость Рекомендация
Datacenter 30-40% Высокая Низкая Только с headless-браузерами
Residential 85-95% Средняя Высокая Оптимальный выбор
Mobile 90-98% Средняя Очень высокая Для критичных задач
ISP (Static Residential) 80-90% Высокая Средняя Баланс цены и качества

Почему резидентные прокси эффективнее

Резидентные прокси используют IP-адреса реальных устройств (домашние роутеры, смартфоны). Cloudflare не может массово блокировать такие IP, так как это заблокирует обычных пользователей. Статистика показывает, что резидентные IP получают капчу в 15-20 раз реже, чем дата-центры.

При работе с резидентными прокси критически важна геолокация. Если целевой сайт ориентирован на США, использование прокси из Азии повысит подозрительность. Выбирайте провайдеров с широкой географией и возможностью таргетинга по городам.

Мобильные прокси для максимальной надёжности

Мобильные прокси используют IP-адреса мобильных операторов (4G/5G). Особенность мобильных сетей — динамическая смена IP через режим полёта, что даёт практически неограниченное количество чистых IP-адресов. Вероятность блокировки мобильного IP близка к нулю.

# Пример ротации мобильного IP через API
import requests
import time

def rotate_mobile_ip(proxy_api_url):
    """Смена IP мобильного прокси"""
    response = requests.get(f"{proxy_api_url}/rotate")
    if response.status_code == 200:
        print("IP успешно изменён")
        time.sleep(5)  # Ожидание применения изменений
        return True
    return False

# Использование с мобильным прокси
mobile_proxy = "http://user:pass@mobile.proxy.com:8080"

for i in range(10):
    # Выполнение запроса
    response = requests.get(
        'https://example.com',
        proxies={'http': mobile_proxy, 'https': mobile_proxy}
    )
    
    # Ротация IP после каждого запроса
    rotate_mobile_ip('https://api.proxy.com/mobile')

Управление cookies и сессиями

После успешного прохождения Cloudflare challenge сервер устанавливает cookies (cf_clearance, __cfduid и другие), которые подтверждают легитимность клиента. Правильное управление этими cookies позволяет избежать повторных проверок.

Извлечение и переиспользование cf_clearance

Cookie cf_clearance обычно действителен 30-60 минут. После получения через headless-браузер, его можно использовать в обычных HTTP-запросах.

import requests
import pickle
from datetime import datetime, timedelta

class CloudflareCookieManager:
    def __init__(self, cookie_file='cf_cookies.pkl'):
        self.cookie_file = cookie_file
        self.cookies = self.load_cookies()
    
    def load_cookies(self):
        """Загрузка сохранённых cookies"""
        try:
            with open(self.cookie_file, 'rb') as f:
                data = pickle.load(f)
                # Проверка срока действия
                if data['expires'] > datetime.now():
                    return data['cookies']
        except FileNotFoundError:
            pass
        return None
    
    def save_cookies(self, cookies, ttl_minutes=30):
        """Сохранение cookies с TTL"""
        data = {
            'cookies': cookies,
            'expires': datetime.now() + timedelta(minutes=ttl_minutes)
        }
        with open(self.cookie_file, 'wb') as f:
            pickle.dump(data, f)
    
    def get_cf_clearance(self, url, proxy):
        """Получение cf_clearance через браузер"""
        if self.cookies:
            return self.cookies
        
        # Здесь код запуска браузера (из предыдущего раздела)
        # ...
        browser_cookies = bypass_cloudflare(url, proxy)['cookies']
        
        # Конвертация в формат requests
        cookies_dict = {c['name']: c['value'] for c in browser_cookies}
        self.save_cookies(cookies_dict)
        self.cookies = cookies_dict
        
        return cookies_dict
    
    def make_request(self, url, proxy):
        """Запрос с автоматическим управлением cookies"""
        cookies = self.get_cf_clearance(url, proxy)
        
        response = requests.get(
            url,
            cookies=cookies,
            proxies={'http': proxy, 'https': proxy},
            headers=get_random_headers()
        )
        
        # Если получили challenge снова — обновляем cookies
        if response.status_code == 403 or 'cf-browser-verification' in response.text:
            print("Cookies устарели, получение новых...")
            self.cookies = None
            return self.make_request(url, proxy)
        
        return response

# Использование
manager = CloudflareCookieManager()
response = manager.make_request(
    'https://example.com/api/data',
    'http://user:pass@proxy.example.com:8080'
)

Привязка cookies к IP-адресу

Cloudflare привязывает cf_clearance к IP-адресу, с которого был пройден challenge. Использование этого cookie с другого IP приведёт к блокировке. При работе с ротирующимися прокси необходимо хранить отдельный набор cookies для каждого IP.

import hashlib

class IPBoundCookieManager:
    def __init__(self):
        self.cookies_by_ip = {}
    
    def get_ip_hash(self, proxy_url):
        """Создание хеша для идентификации прокси"""
        return hashlib.md5(proxy_url.encode()).hexdigest()
    
    def get_cookies_for_proxy(self, proxy_url, target_url):
        """Получение cookies для конкретного прокси"""
        ip_hash = self.get_ip_hash(proxy_url)
        
        if ip_hash in self.cookies_by_ip:
            cookies_data = self.cookies_by_ip[ip_hash]
            if cookies_data['expires'] > datetime.now():
                return cookies_data['cookies']
        
        # Получение новых cookies через браузер
        new_cookies = self.fetch_cookies_with_browser(target_url, proxy_url)
        
        self.cookies_by_ip[ip_hash] = {
            'cookies': new_cookies,
            'expires': datetime.now() + timedelta(minutes=30)
        }
        
        return new_cookies

Ротация прокси и контроль частоты запросов

Даже с правильным техническим стеком слишком высокая частота запросов с одного IP триггерит rate limiting. Cloudflare анализирует паттерны трафика и выявляет аномальную активность.

Стратегии ротации прокси

Существует три основных подхода к ротации: round-robin (последовательная), random (случайная) и sticky sessions (привязка к сессии). Для обхода Cloudflare оптимальна стратегия sticky sessions с ограничением запросов на IP.

import time
import random
from collections import defaultdict
from datetime import datetime, timedelta

class SmartProxyRotator:
    def __init__(self, proxy_list, max_requests_per_ip=20, cooldown_minutes=10):
        self.proxy_list = proxy_list
        self.max_requests_per_ip = max_requests_per_ip
        self.cooldown_minutes = cooldown_minutes
        
        # Счётчики использования
        self.usage_count = defaultdict(int)
        self.last_used = {}
        self.cooldown_until = {}
    
    def get_proxy(self):
        """Получение следующего доступного прокси"""
        available_proxies = []
        
        for proxy in self.proxy_list:
            # Проверка cooldown
            if proxy in self.cooldown_until:
                if datetime.now() < self.cooldown_until[proxy]:
                    continue
                else:
                    # Сброс счётчика после cooldown
                    self.usage_count[proxy] = 0
                    del self.cooldown_until[proxy]
            
            # Проверка лимита запросов
            if self.usage_count[proxy] < self.max_requests_per_ip:
                available_proxies.append(proxy)
        
        if not available_proxies:
            # Если все прокси в cooldown — ждём
            wait_time = min(
                (self.cooldown_until[p] - datetime.now()).total_seconds()
                for p in self.cooldown_until
            )
            print(f"Все прокси в cooldown. Ожидание {wait_time:.0f} секунд...")
            time.sleep(wait_time + 1)
            return self.get_proxy()
        
        # Выбор прокси с наименьшим использованием
        proxy = min(available_proxies, key=lambda p: self.usage_count[p])
        
        self.usage_count[proxy] += 1
        self.last_used[proxy] = datetime.now()
        
        # Установка cooldown при достижении лимита
        if self.usage_count[proxy] >= self.max_requests_per_ip:
            self.cooldown_until[proxy] = datetime.now() + timedelta(
                minutes=self.cooldown_minutes
            )
            print(f"Прокси {proxy} достиг лимита. Cooldown {self.cooldown_minutes} минут.")
        
        return proxy
    
    def add_delay(self):
        """Случайная задержка между запросами (имитация человека)"""
        delay = random.uniform(2, 5)  # 2-5 секунд
        time.sleep(delay)

# Использование
proxy_pool = [
    'http://user:pass@proxy1.example.com:8080',
    'http://user:pass@proxy2.example.com:8080',
    'http://user:pass@proxy3.example.com:8080',
    # ... до 50-100 прокси для стабильной работы
]

rotator = SmartProxyRotator(
    proxy_pool,
    max_requests_per_ip=15,  # Консервативное значение
    cooldown_minutes=15
)

# Выполнение запросов
for i in range(1000):
    proxy = rotator.get_proxy()
    
    response = requests.get(
        'https://example.com/page',
        proxies={'http': proxy, 'https': proxy},
        headers=get_random_headers()
    )
    
    print(f"Запрос {i+1}: {response.status_code}")
    rotator.add_delay()

Адаптивный rate limiting

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

class AdaptiveRateLimiter:
    def __init__(self, initial_delay=3.0):
        self.delay = initial_delay
        self.min_delay = 1.0
        self.max_delay = 30.0
        self.success_streak = 0
        self.failure_streak = 0
    
    def on_success(self):
        """Успешный запрос — можно ускориться"""
        self.success_streak += 1
        self.failure_streak = 0
        
        if self.success_streak >= 10:
            # Уменьшаем задержку на 10%
            self.delay = max(self.min_delay, self.delay * 0.9)
            self.success_streak = 0
    
    def on_failure(self, status_code):
        """Ошибка — замедляемся"""
        self.failure_streak += 1
        self.success_streak = 0
        
        if status_code == 429:  # Rate limit
            # Агрессивное замедление
            self.delay = min(self.max_delay, self.delay * 2.0)
        elif status_code == 403:  # Возможная блокировка
            self.delay = min(self.max_delay, self.delay * 1.5)
        
        print(f"Задержка увеличена до {self.delay:.2f}s")
    
    def wait(self):
        """Ожидание перед следующим запросом"""
        # Добавляем случайность ±20%
        actual_delay = self.delay * random.uniform(0.8, 1.2)
        time.sleep(actual_delay)

Готовые инструменты и библиотеки для обхода

Разработка собственного решения с нуля требует времени и экспертизы. Существуют готовые инструменты, которые автоматизируют процесс обхода Cloudflare.

cloudscraper (Python)

Библиотека cloudscraper — надстройка над requests, которая автоматически решает JavaScript challenges. Работает с базовыми защитами, но может не справиться с продвинутыми проверками.

import cloudscraper

# Создание scraper с поддержкой прокси
scraper = cloudscraper.create_scraper(
    browser={
        'browser': 'chrome',
        'platform': 'windows',
        'desktop': True
    }
)

# Настройка прокси
proxies = {
    'http': 'http://user:pass@proxy.example.com:8080',
    'https': 'http://user:pass@proxy.example.com:8080'
}

# Выполнение запроса
response = scraper.get('https://example.com', proxies=proxies)

if response.status_code == 200:
    print("Успешный обход")
    print(response.text)
else:
    print(f"Ошибка: {response.status_code}")

FlareSolverr (универсальный)

FlareSolverr — прокси-сервер, который запускает headless-браузер для решения Cloudflare challenges. Работает через HTTP API, поддерживает любые языки программирования.

# Запуск FlareSolverr через Docker
docker run -d \
  --name=flaresolverr \
  -p 8191:8191 \
  -e LOG_LEVEL=info \
  ghcr.io/flaresolverr/flaresolverr:latest

# Использование из Python
import requests

def solve_cloudflare(url, proxy=None):
    flaresolverr_url = "http://localhost:8191/v1"
    
    payload = {
        "cmd": "request.get",
        "url": url,
        "maxTimeout": 60000
    }
    
    if proxy:
        payload["proxy"] = {
            "url": proxy
        }
    
    response = requests.post(flaresolverr_url, json=payload)
    result = response.json()
    
    if result['status'] == 'ok':
        return {
            'html': result['solution']['response'],
            'cookies': result['solution']['cookies'],
            'user_agent': result['solution']['userAgent']
        }
    else:
        raise Exception(f"FlareSolverr error: {result['message']}")

# Пример использования
result = solve_cloudflare(
    'https://example.com',
    proxy='http://user:pass@proxy.example.com:8080'
)

print(result['html'])

undetected-chromedriver

Патченная версия Selenium ChromeDriver, которая автоматически применяет множество техник anti-detect. Проще в использовании, чем Playwright, но менее гибкая.

import undetected_chromedriver as uc
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

def bypass_with_uc(url, proxy):
    options = uc.ChromeOptions()
    options.add_argument(f'--proxy-server={proxy}')
    options.add_argument('--disable-blink-features=AutomationControlled')
    
    driver = uc.Chrome(options=options, version_main=120)
    
    try:
        driver.get(url)
        
        # Ожидание исчезновения Cloudflare challenge
        WebDriverWait(driver, 20).until_not(
            EC.presence_of_element_located((By.ID, "cf-spinner-please-wait"))
        )
        
        # Дополнительное ожидание для надёжности
        time.sleep(3)
        
        # Получение результата
        html = driver.page_source
        cookies = driver.get_cookies()
        
        return {'html': html, 'cookies': cookies}
    
    finally:
        driver.quit()

# Использование
result = bypass_with_uc(
    'https://example.com',
    'http://user:pass@proxy.example.com:8080'
)

Комбинированный подход: Оптимальная стратегия — использовать headless-браузер только для первичного получения cookies, затем переключаться на HTTP-клиенты (tls-client, cloudscraper) с этими cookies. Это даёт баланс между надёжностью и производительностью.

Заключение

Обход Cloudflare при работе через прокси требует комплексного подхода: правильный TLS fingerprint, аутентичные HTTP-заголовки, качественные прокси и грамотное управление сессиями. Ключевые рекомендации:

  • Используйте резидентные или мобильные прокси вместо дата-центров
  • Применяйте библиотеки с правильным TLS fingerprint (tls-client, curl-impersonate)
  • Для сложных случаев используйте headless-браузеры с anti-detect патчами
  • Сохраняйте и переиспользуйте cf_clearance cookies
  • Ротируйте прокси с учётом rate limiting (не более 15-20 запросов на IP)
  • Добавляйте случайные задержки между запросами (2-5 секунд)

Защита Cloudflare постоянно эволюционирует, поэтому важно регулярно обновлять инструменты и адаптировать стратегии. Мониторьте изменения в fingerprinting техниках и тестируйте решения на актуальных версиях защиты.

Для стабильной работы рекомендуется использовать профессиональные прокси-сервисы с широким пулом IP и автоматической ротацией.