Voltar ao blog

Como contornar a detecção do Cloudflare ao usar proxies

A Cloudflare bloqueia suas solicitações através de um proxy? Analisamos métodos técnicos para contornar a detecção: desde a configuração correta do TLS até o uso de navegadores headless com exemplos reais.

📅17 de dezembro de 2025
```html

7 maneiras comprovadas de contornar a detecção do Cloudflare ao usar proxy

O Cloudflare processa mais de 20% de todo o tráfego da web e utiliza um sistema de proteção contra bots em múltiplas camadas. Ao trabalhar através de servidores proxy, a probabilidade de receber um captcha ou bloqueio aumenta drasticamente. Neste guia, vamos explorar os aspectos técnicos da detecção e métodos práticos de contorno que funcionam em 2024.

Como o Cloudflare identifica proxies e bots

O Cloudflare utiliza um sistema abrangente de análise que verifica dezenas de parâmetros de cada solicitação. Compreender os mecanismos de detecção é o primeiro passo para contornar com sucesso a proteção.

Principais métodos de detecção

TLS Fingerprinting: O Cloudflare analisa os parâmetros do handshake SSL/TLS (cipher suites, extensões, ordem de ocorrência). Cada cliente HTTP tem uma "impressão digital" única. Por exemplo, o Python requests utiliza OpenSSL com um conjunto característico de cifras, que é facilmente distinguível do Chrome ou Firefox.

Ao analisar a solicitação, o Cloudflare compara o TLS fingerprint com o User-Agent declarado. Se você especifica Chrome 120, mas os parâmetros TLS correspondem ao Python requests — isso resulta em uma detecção imediata de bot.

Parâmetro de verificação O que é analisado Risco de detecção
TLS fingerprint Cipher suites, extensões, versão TLS Alto
HTTP/2 fingerprint Ordem dos cabeçalhos, frames SETTINGS Alto
Reputação do IP Histórico do IP, pertencente a data centers Médio
Desafio JavaScript Execução de JS, canvas fingerprint, WebGL Alto
Análise comportamental Padrões de solicitações, timing, movimentos do mouse Médio

Desde 2023, o Cloudflare utiliza ativamente aprendizado de máquina para analisar padrões comportamentais. O sistema monitora não apenas os parâmetros técnicos, mas também os intervalos de tempo entre as solicitações, a sequência de ações do usuário, movimentos do mouse e rolagem da página.

Mascaramento do TLS fingerprint

O TLS fingerprinting é o método mais eficaz de detecção de bots. Clientes HTTP padrão (requests, curl, axios) geram um fingerprint que é impossível de confundir com um navegador real. A solução é usar bibliotecas especializadas que imitam o comportamento TLS dos navegadores.

Uso do curl-impersonate

A biblioteca curl-impersonate é uma versão modificada do curl que replica com precisão os TLS e HTTP/2 fingerprints dos navegadores populares. Suporta Chrome, Firefox, Safari e Edge.

# Instalação do curl-impersonate
git clone https://github.com/lwthiker/curl-impersonate
cd curl-impersonate
make chrome-build

# Uso com imitação do 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: biblioteca tls-client

Para Python, existe uma wrapper chamada tls-client, que utiliza curl-impersonate por trás e fornece uma interface semelhante ao requests.

import tls_client

# Criação de sessão com fingerprint do Chrome 120
session = tls_client.Session(
    client_identifier="chrome_120",
    random_tls_extension_order=True
)

# Configuração do proxy
proxies = {
    'http': 'http://username:password@proxy.example.com:8080',
    'https': 'http://username:password@proxy.example.com:8080'
}

# Execução da solicitação
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)

Importante: Ao usar o tls-client, é crucial que o User-Agent nos cabeçalhos corresponda ao client_identifier escolhido. A discrepância resultará em detecção imediata.

Verificação do TLS fingerprint

Antes de começar a fazer scraping, é recomendável verificar seu TLS fingerprint. Use serviços como tls.peet.ws ou ja3er.com para análise.

# Verificação do fingerprint
response = session.get('https://tls.peet.ws/api/all')
print(response.json()['tls']['ja3'])

# Compare com o fingerprint do Chrome real:
# https://kawayiyi.com/tls-fingerprint-database/

Configuração correta dos cabeçalhos HTTP

Mesmo com o TLS fingerprint correto, cabeçalhos HTTP incorretos revelarão um bot. O Cloudflare analisa não apenas a presença dos cabeçalhos, mas também sua ordem, formato dos valores e coerência lógica.

Cabeçalhos obrigatórios para 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'
}

Os cabeçalhos Sec-Ch-Ua-* apareceram no Chrome 89 e fazem parte da API Client Hints. A ausência deles ao usar um User-Agent moderno é um sinal claro de bot.

A ordem dos cabeçalhos importa

No HTTP/2, a ordem dos cabeçalhos é fixa para cada navegador. O Python requests e outros clientes padrão enviam cabeçalhos em ordem alfabética, o que difere do comportamento dos navegadores. Use bibliotecas que suportem a ordem personalizada dos cabeçalhos.

Dica: Use as DevTools do navegador (aba Network → clique direito na solicitação → Copy → Copy as cURL) para obter uma cópia exata dos cabeçalhos de um navegador real. Em seguida, adapte-os ao seu código.

Geração dinâmica de User-Agent

Usar o mesmo User-Agent para todas as solicitações aumenta o risco de detecção. Crie um pool de User-Agents atualizados e rotacione-os.

import random

# Pool de User-Agents atualizados (dezembro de 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)
    
    # Adaptação de outros cabeçalhos para o UA escolhido
    if 'Chrome' in ua:
        return {
            'User-Agent': ua,
            'Sec-Ch-Ua': '"Not_A Brand";v="8", "Chromium";v="120"',
            # ... outros cabeçalhos do Chrome
        }
    elif 'Firefox' in ua:
        return {
            'User-Agent': ua,
            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
            # ... cabeçalhos do Firefox
        }
    # ... tratamento de outros navegadores

Uso de navegadores headless

Quando o Cloudflare utiliza desafios JavaScript ou detecção avançada, a única maneira confiável de contornar é através de um navegador real. Navegadores headless processam automaticamente JavaScript, cookies e criam um fingerprint totalmente autêntico.

Playwright com patches anti-detect

O Playwright é uma alternativa moderna ao Selenium com melhor desempenho. No entanto, o Playwright padrão é facilmente detectável através de navigator.webdriver e outros marcadores. Use playwright-stealth para mascaramento.

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)  # Aplicação de patches anti-detect
        
        # Acesso à página
        page.goto(url, wait_until='networkidle', timeout=30000)
        
        # Espera pela conclusão do desafio do Cloudflare (geralmente 5-10 segundos)
        page.wait_for_timeout(8000)
        
        # Verificação de contorno bem-sucedido
        if 'Just a moment' in page.content():
            print('Desafio do Cloudflare não superado')
            return None
        
        # Extração de cookies para uso posterior
        cookies = context.cookies()
        html = page.content()
        
        browser.close()
        return {'html': html, 'cookies': cookies}

# Uso
proxy_config = {
    'host': 'proxy.example.com',
    'port': 8080,
    'username': 'user',
    'password': 'pass'
}

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

Puppeteer Extra com plugins

Para o ecossistema Node.js, a melhor solução é o puppeteer-extra com o plugin puppeteer-extra-plugin-stealth. Este plugin aplica mais de 30 técnicas diferentes de mascaramento de automação.

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();
    
    // Configuração de viewport e user-agent
    await page.setViewport({ width: 1920, height: 1080 });
    await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36');
    
    // Redefinição de navigator.webdriver
    await page.evaluateOnNewDocument(() => {
        delete Object.getPrototypeOf(navigator).webdriver;
    });
    
    // Acesso à página
    await page.goto(url, { waitUntil: 'networkidle2', timeout: 30000 });
    
    // Espera pela conclusão do desafio
    await page.waitForTimeout(8000);
    
    // Obtenção do conteúdo e cookies
    const content = await page.content();
    const cookies = await page.cookies();
    
    await browser.close();
    
    return { content, cookies };
}

// Exemplo de uso
bypassCloudflare('https://example.com', 'http://user:pass@proxy.example.com:8080')
    .then(result => console.log('Sucesso'))
    .catch(err => console.error(err));

Desempenho: Navegadores headless consomem significativamente mais recursos (200-500 MB de RAM por instância). Para tarefas de alta carga, use-os apenas para obter cookies, depois mude para clientes HTTP com esses cookies.

Escolha do tipo de proxy para contorno do Cloudflare

O tipo de proxy tem um impacto crítico no sucesso do contorno. O Cloudflare mantém bancos de dados de endereços IP de data centers e aplica regras de verificação mais rigorosas a eles.

Tipo de proxy Probabilidade de contorno Velocidade Custo Recomendação
Datacenter 30-40% Alta Baixa Apenas com navegadores headless
Residencial 85-95% Média Alta Escolha ideal
Móvel 90-98% Média Muito alta Para tarefas críticas
ISP (Residencial Estático) 80-90% Alta Média Equilíbrio entre custo e qualidade

Por que proxies residenciais são mais eficazes

Proxies residenciais utilizam endereços IP de dispositivos reais (roteadores domésticos, smartphones). O Cloudflare não pode bloquear esses IPs em massa, pois isso bloquearia usuários comuns. Estatísticas mostram que IPs residenciais recebem captcha 15-20 vezes menos frequentemente do que data centers.

Ao trabalhar com proxies residenciais, a geolocalização é crítica. Se o site-alvo é voltado para os EUA, usar proxies da Ásia aumentará a suspeita. Escolha provedores com ampla geografia e capacidade de segmentação por cidades.

Proxies móveis para máxima confiabilidade

Proxies móveis utilizam endereços IP de operadoras móveis (4G/5G). A característica das redes móveis é a troca dinâmica de IP através do modo avião, o que oferece praticamente um número ilimitado de IPs limpos. A probabilidade de bloqueio de um IP móvel é próxima de zero.

# Exemplo de rotação de IP móvel através da API
import requests
import time

def rotate_mobile_ip(proxy_api_url):
    """Troca de IP do proxy móvel"""
    response = requests.get(f"{proxy_api_url}/rotate")
    if response.status_code == 200:
        print("IP alterado com sucesso")
        time.sleep(5)  # Espera pela aplicação das mudanças
        return True
    return False

# Uso com proxy móvel
mobile_proxy = "http://user:pass@mobile.proxy.com:8080"

for i in range(10):
    # Execução da solicitação
    response = requests.get(
        'https://example.com',
        proxies={'http': mobile_proxy, 'https': mobile_proxy}
    )
    
    # Rotação de IP após cada solicitação
    rotate_mobile_ip('https://api.proxy.com/mobile')

Gerenciamento de cookies e sessões

Após passar com sucesso pelo desafio do Cloudflare, o servidor define cookies (cf_clearance, __cfduid e outros) que confirmam a legitimidade do cliente. O gerenciamento correto desses cookies permite evitar verificações repetidas.

Extração e reutilização do cf_clearance

O cookie cf_clearance geralmente é válido por 30-60 minutos. Após obtê-lo através de um navegador headless, ele pode ser usado em solicitações HTTP normais.

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):
        """Carregar cookies salvos"""
        try:
            with open(self.cookie_file, 'rb') as f:
                data = pickle.load(f)
                # Verificação de validade
                if data['expires'] > datetime.now():
                    return data['cookies']
        except FileNotFoundError:
            pass
        return None
    
    def save_cookies(self, cookies, ttl_minutes=30):
        """Salvar cookies com 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):
        """Obter cf_clearance através do navegador"""
        if self.cookies:
            return self.cookies
        
        # Aqui vai o código para iniciar o navegador (da seção anterior)
        # ...
        browser_cookies = bypass_cloudflare(url, proxy)['cookies']
        
        # Conversão para o formato 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):
        """Solicitação com gerenciamento automático de cookies"""
        cookies = self.get_cf_clearance(url, proxy)
        
        response = requests.get(
            url,
            cookies=cookies,
            proxies={'http': proxy, 'https': proxy},
            headers=get_random_headers()
        )
        
        # Se receber o desafio novamente — atualiza os cookies
        if response.status_code == 403 or 'cf-browser-verification' in response.text:
            print("Cookies expiraram, obtendo novos...")
            self.cookies = None
            return self.make_request(url, proxy)
        
        return response

# Uso
manager = CloudflareCookieManager()
response = manager.make_request(
    'https://example.com/api/data',
    'http://user:pass@proxy.example.com:8080'
)

Vínculo de cookies ao endereço IP

O Cloudflare vincula o cf_clearance ao endereço IP a partir do qual o desafio foi superado. Usar esse cookie de outro IP resultará em bloqueio. Ao trabalhar com proxies rotativos, é necessário manter um conjunto separado de cookies para cada IP.

import hashlib

class IPBoundCookieManager:
    def __init__(self):
        self.cookies_by_ip = {}
    
    def get_ip_hash(self, proxy_url):
        """Criação de hash para identificação do proxy"""
        return hashlib.md5(proxy_url.encode()).hexdigest()
    
    def get_cookies_for_proxy(self, proxy_url, target_url):
        """Obter cookies para um proxy específico"""
        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']
        
        # Obtenção de novos cookies através do navegador
        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

Rotação de proxies e controle da frequência de solicitações

Mesmo com a pilha técnica correta, uma frequência de solicitações muito alta de um único IP aciona o rate limiting. O Cloudflare analisa padrões de tráfego e identifica atividades anômalas.

Estratégias de rotação de proxies

Existem três abordagens principais para rotação: round-robin (sequencial), random (aleatória) e sticky sessions (vinculação à sessão). Para contornar o Cloudflare, a estratégia ideal é sticky sessions com limitação de solicitações por 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
        
        # Contadores de uso
        self.usage_count = defaultdict(int)
        self.last_used = {}
        self.cooldown_until = {}
    
    def get_proxy(self):
        """Obter o próximo proxy disponível"""
        available_proxies = []
        
        for proxy in self.proxy_list:
            # Verificação de cooldown
            if proxy in self.cooldown_until:
                if datetime.now() < self.cooldown_until[proxy]:
                    continue
                else:
                    # Resetar contador após cooldown
                    self.usage_count[proxy] = 0
                    del self.cooldown_until[proxy]
            
            # Verificação do limite de solicitações
            if self.usage_count[proxy] < self.max_requests_per_ip:
                available_proxies.append(proxy)
        
        if not available_proxies:
            # Se todos os proxies estiverem em cooldown — aguardar
            wait_time = min(
                (self.cooldown_until[p] - datetime.now()).total_seconds()
                for p in self.cooldown_until
            )
            print(f"Todos os proxies estão em cooldown. Aguardando {wait_time:.0f} segundos...")
            time.sleep(wait_time + 1)
            return self.get_proxy()
        
        # Escolher proxy com menor uso
        proxy = min(available_proxies, key=lambda p: self.usage_count[p])
        
        self.usage_count[proxy] += 1
        self.last_used[proxy] = datetime.now()
        
        # Estabelecer cooldown ao atingir o limite
        if self.usage_count[proxy] >= self.max_requests_per_ip:
            self.cooldown_until[proxy] = datetime.now() + timedelta(
                minutes=self.cooldown_minutes
            )
            print(f"O proxy {proxy} atingiu o limite. Cooldown de {self.cooldown_minutes} minutos.")
        
        return proxy
    
    def add_delay(self):
        """Atraso aleatório entre solicitações (imitação de humano)"""
        delay = random.uniform(2, 5)  # 2-5 segundos
        time.sleep(delay)

# Uso
proxy_pool = [
    'http://user:pass@proxy1.example.com:8080',
    'http://user:pass@proxy2.example.com:8080',
    'http://user:pass@proxy3.example.com:8080',
    # ... até 50-100 proxies para operação estável
]

rotator = SmartProxyRotator(
    proxy_pool,
    max_requests_per_ip=15,  # Valor conservador
    cooldown_minutes=15
)

# Execução de solicitações
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"Solicitação {i+1}: {response.status_code}")
    rotator.add_delay()

Rate limiting adaptativo

Uma abordagem mais avançada é a adaptação dinâmica da frequência de solicitações com base nas respostas do servidor. Se começarem a aparecer erros 429 ou captchas, reduza automaticamente a velocidade.

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):
        """Solicitação bem-sucedida — pode acelerar"""
        self.success_streak += 1
        self.failure_streak = 0
        
        if self.success_streak >= 10:
            # Reduzir atraso em 10%
            self.delay = max(self.min_delay, self.delay * 0.9)
            self.success_streak = 0
    
    def on_failure(self, status_code):
        """Erro — desacelera"""
        self.failure_streak += 1
        self.success_streak = 0
        
        if status_code == 429:  # Rate limit
            # Atraso agressivo
            self.delay = min(self.max_delay, self.delay * 2.0)
        elif status_code == 403:  # Possível bloqueio
            self.delay = min(self.max_delay, self.delay * 1.5)
        
        print(f"Atraso aumentado para {self.delay:.2f}s")
    
    def wait(self):
        """Aguardar antes da próxima solicitação"""
        # Adiciona aleatoriedade ±20%
        actual_delay = self.delay * random.uniform(0.8, 1.2)
        time.sleep(actual_delay)

Ferramentas e bibliotecas prontas para contorno

O desenvolvimento de uma solução própria do zero requer tempo e experiência. Existem ferramentas prontas que automatizam o processo de contorno do Cloudflare.

cloudscraper (Python)

A biblioteca cloudscraper é uma extensão do requests que resolve automaticamente desafios JavaScript. Funciona com proteções básicas, mas pode não lidar com verificações avançadas.

import cloudscraper

# Criação de scraper com suporte a proxy
scraper = cloudscraper.create_scraper(
    browser={
        'browser': 'chrome',
        'platform': 'windows',
        'desktop': True
    }
)

# Configuração do proxy
proxies = {
    'http': 'http://user:pass@proxy.example.com:8080',
    'https': 'http://user:pass@proxy.example.com:8080'
}

# Execução da solicitação
response = scraper.get('https://example.com', proxies=proxies)

if response.status_code == 200:
    print("Contorno bem-sucedido")
    print(response.text)
else:
    print(f"Erro: {response.status_code}")

FlareSolverr (universal)

O FlareSolverr é um servidor proxy que executa um navegador headless para resolver desafios do Cloudflare. Funciona através de uma API HTTP, suportando qualquer linguagem de programação.

# Execução do FlareSolverr via Docker
docker run -d \
  --name=flaresolverr \
  -p 8191:8191 \
  -e LOG_LEVEL=info \
  ghcr.io/flaresolverr/flaresolverr:latest

# Uso a partir do 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"Erro do FlareSolverr: {result['message']}")

# Exemplo de uso
result = solve_cloudflare(
    'https://example.com',
    proxy='http://user:pass@proxy.example.com:8080'
)

print(result['html'])

undetected-chromedriver

Uma versão patch do Selenium ChromeDriver que aplica automaticamente várias técnicas anti-detect. Mais fácil de usar do que o Playwright, mas menos flexível.

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)
        
        # Espera pelo desaparecimento do desafio do Cloudflare
        WebDriverWait(driver, 20).until_not(
            EC.presence_of_element_located((By.ID, "cf-spinner-please-wait"))
        )
        
        # Espera adicional para confiabilidade
        time.sleep(3)
        
        # Obtenção do resultado
        html = driver.page_source
        cookies = driver.get_cookies()
        
        return {'html': html, 'cookies': cookies}
    
    finally:
        driver.quit()

# Uso
result = bypass_with_uc(
    'https://example.com',
    'http://user:pass@proxy.example.com:8080'
)

Abordagem combinada: A estratégia ideal é usar um navegador headless apenas para a obtenção inicial de cookies, depois mudar para clientes HTTP (tls-client, cloudscraper) com esses cookies. Isso proporciona um equilíbrio entre confiabilidade e desempenho.

Conclusão

Contornar o Cloudflare ao usar proxies requer uma abordagem abrangente: fingerprint TLS correto, cabeçalhos HTTP autênticos, proxies de qualidade e gerenciamento adequado de sessões. Recomendações principais:

  • Use proxies residenciais ou proxies móveis em vez de data centers
  • Utilize bibliotecas com o fingerprint TLS correto (tls-client, curl-impersonate)
  • Para casos complexos, use navegadores headless com patches anti-detect
  • Salve e reutilize cookies cf_clearance
  • Rotacione proxies considerando o rate limiting (não mais de 15-20 solicitações por IP)
  • Adicione atrasos aleatórios entre solicitações (2-5 segundos)

A proteção do Cloudflare está em constante evolução, portanto, é importante atualizar regularmente as ferramentas e adaptar as estratégias. Monitore as mudanças nas técnicas de fingerprinting e teste soluções em versões atuais da proteção.

Para um funcionamento estável, recomenda-se usar serviços de proxy profissionais com um amplo pool de IPs e rotação automática.

```