Rotação de Proxy no Crawlee para Python: Guia para Produção

Aprenda a integrar rotação de proxy no Crawlee para Python usando ProxyConfiguration, SessionPool e proxies residenciais do ProxyHat. Exemplos executáveis e padrões de produção incluídos.

Proxy Rotation in Crawlee for Python: A Developer's Guide to Residential Proxies
Neste artigo

Se você está construindo crawlers em Python com o framework Crawlee, a rotação de proxy no Crawlee para Python não é um recurso opcional — é uma necessidade para qualquer pipeline de coleta de dados que precise escalar além de algumas centenas de requisições. Neste guia, vamos além do básico: mostramos como usar a classe ProxyConfiguration de forma idiomática, integrar proxies residenciais do ProxyHat via gate.proxyhat.com:8080, e adotar padrões de produção como session.retire() e fallback em camadas.

Aviso legal: Este guia trata exclusivamente de dados públicos. Respeite o robots.txt, os Termos de Serviço dos sites e as leis aplicáveis como o RGPD e a CFAA. Sempre prefira APIs oficiais quando disponíveis. A coleta de dados pessoais sem consentimento pode violar legislações de privacidade.

Por que a rotação de proxy no Crawlee para Python importa

O Crawlee para Python (documentação oficial) é um framework de crawling moderno que unifica crawlers baseados em HTTP (BeautifulSoupCrawler, ParselCrawler) e em navegador (PlaywrightCrawler) sobre uma mesma infraestrutura: fila de requisições unificada, pool de sessões, autoscaling e roteamento configurável. Essa arquitetura é poderosa, mas também significa que o gerenciamento de proxies precisa ser tratado no nível do framework — não como um patch no código do seu handler.

Sites modernos usam sistemas anti-bot como Cloudflare, DataDome e PerimeterX. Esses sistemas analisam padrões de tráfego: taxa de requisições por IP, consistência de cookies, fingerprints de TLS e comportamento de navegação. Um único IP datacenter fazendo 200 requisições por minuto é um sinal óbvio. A rotação de proxy distribui essas requisições entre múltiplos IPs, reduzindo a probabilidade de bloqueio.

Mas rotação não é apenas trocar de IP a cada requisição. Em muitos cenários, você precisa manter o mesmo IP por sessão — para preservar cookies, tokens de autenticação e estado de navegação. É aqui que o SessionPool do Crawlee entra em cena, acoplando cookies e fingerprints a IPs específicos.

Arquitetura do Crawlee: como proxies se encaixam

O Crawlee para Python organiza o crawling em camadas bem definidas:

  • Fila de requisições unificada (RequestQueue): armazena URLs a visitar, com deduplicação e estado. Tanto BeautifulSoupCrawler quanto PlaywrightCrawler consomem da mesma fila.
  • Pool de sessões (SessionPool): gerencia sessões que combinam cookies, user-agent, headers e — crucialmente — um proxy vinculado. Cada sessão tem um ID e um ciclo de vida.
  • ProxyConfiguration: classe responsável por gerar URLs de proxy, seja em rotação round-robin ou fixadas por sessão.
  • Pool autoscalado (AutoscaledPool): controla concorrência, ajustando o número de requisições simultâneas com base na performance do sistema.
  • Rotas (router): permitem direcionar requisições para handlers diferentes baseado em labels.

A integração de proxies acontece em duas camadas: o ProxyConfiguration gera a URL do proxy, e o SessionPool decide qual sessão (e portanto qual proxy) usar para cada requisição. Quando uma sessão é bloqueada, ela é retirada (retire()), e uma nova sessão com um novo proxy é criada automaticamente.

BeautifulSoupCrawler vs PlaywrightCrawler: quando usar cada um

Aspecto BeautifulSoupCrawler PlaywrightCrawler
Motor de renderização HTTP + parsing HTML Browser headless (Chromium)
Consumo de recursos Baixo (~50 MB por worker) Alto (~200–300 MB por instância)
Concorrência típica 50–100 requisições simultâneas 5–20 abas simultâneas
JavaScript Não executa Executa completamente
Velocidade por requisição ~200–500 ms ~2–5 s
Ideal para HTML estático, APIs públicas SPAs, conteúdo dinâmico, anti-bot avançado

Use PlaywrightCrawler apenas quando o conteúdo depender de JavaScript ou quando o anti-bot exigir um browser real. Para a maioria dos casos — SERP scraping, monitoramento de preços, coleta de dados estruturados — BeautifulSoupCrawler com proxies residenciais é mais eficiente e escalável.

ProxyConfiguration: a abordagem idiomática

O Crawlee oferece a classe ProxyConfiguration como ponto único de configuração de proxies. Em vez de injetar proxies manualmente em cada requisição, você configura o ProxyConfiguration uma vez e o framework cuida do resto.

Rotação round-robin vs sessão fixa

Existem duas estratégias principais:

  • Round-robin: cada chamada a proxy_configuration.new_url() retorna um proxy diferente. Ideal para scraping de larga escala onde cada requisição é independente.
  • Sessão fixa (session_id): proxy_configuration.new_url(session_id="abc123") retorna sempre o mesmo proxy para essa sessão. Essencial quando você precisa manter cookies e estado de navegação.

Com o ProxyHat, a fixação de sessão é controlada pelo próprio username do proxy. O parâmetro session-abc123 no username garante que o mesmo IP residencial seja retornado enquanto a sessão estiver ativa.

Por que proxies residenciais superam datacenter em alvos protegidos

IPs datacenter são fáceis de detectar: faixas de ASN conhecidas (AWS, Google Cloud, DigitalOcean), sem histórico de navegação real, sem ISP associado. Sistemas como Cloudflare Bot Management e DataDome classificam esses IPs com alta probabilidade de serem bots.

Proxies residenciais usam IPs de dispositivos reais conectados a ISPs legítimos. O tráfego parece orgânico — o ASN é de uma operadora de telecom, o IP tem histórico de navegação normal. Isso não torna a detecção impossível, mas aumenta significativamente o custo e a dificuldade do anti-bot.

Estratégia de fallback em camadas (tiered proxies)

Em produção, a melhor abordagem é usar camadas:

  1. Camada 1 — Residencial: tente primeiro com proxies residenciais. Alta taxa de sucesso (~95–99%), maior latência (~200–800 ms).
  2. Camada 2 — Mobile: se o residencial falhar (CAPTCHA persistente), faça fallback para mobile. IPs de redes 4G/5G são ainda mais confiáveis para anti-bot, mas mais caros.
  3. Camada 3 — Datacenter: último recurso para endpoints que não têm proteção anti-bot. Mais rápido e barato, mas facilmente bloqueável.

No Crawlee, isso se implementa verificando o status da resposta dentro do request_handler e chamando session.retire() quando um bloqueio é detectado, forçando a criação de uma nova sessão.

Exemplo executável: BeautifulSoupCrawler com ProxyHat

Abaixo, um exemplo completo e executável de BeautifulSoupCrawler com ProxyConfiguration apontando para o gateway do ProxyHat, usando sessões fixas com geo-targeting dos EUA.

import asyncio
from crawlee.beautifulsoup_crawler import BeautifulSoupCrawler
from crawlee.proxy_configuration import ProxyConfiguration
from crawlee import Request
import uuid

# Credenciais do ProxyHat
PROXYHAT_USER = "seu_usuario"
PROXYHAT_PASS = "sua_senha"

def build_proxy_url(session_id: str, country: str = "US") -> str:
    """Gera a URL do proxy ProxyHat com sessão fixa e geo-targeting."""
    username = f"{PROXYHAT_USER}-country-{country}-session-{session_id}"
    return f"http://{username}:{PROXYHAT_PASS}@gate.proxyhat.com:8080"

class ProxyHatProxyConfiguration(ProxyConfiguration):
    """ProxyConfiguration customizada que gera URLs do ProxyHat por sessão."""
    
    async def new_url(self, session_id: str | None = None) -> str:
        sid = session_id or str(uuid.uuid4())[:8]
        return build_proxy_url(sid)

async def main():
    proxy_config = ProxyHatProxyConfiguration()
    
    crawler = BeautifulSoupCrawler(
        proxy_configuration=proxy_config,
        max_request_retries=3,
        max_requests_per_crawl=100,
        request_handler_timeout=30,
    )
    
    @crawler.router.default_handler
    async def handler(request: Request, soup, session):
        # Detecta bloqueio: título de CAPTCHA ou status 403
        title = soup.find("title")
        if title and "captcha" in title.text.lower():
            session.retire()
            raise RuntimeError(f"Bloqueio detectado em {request.url}")
        
        # Extrai dados
        h1 = soup.find("h1")
        print(f"[{session.id}] {request.url} -> {h1.text if h1 else 'sem h1'}")
        
        # Adiciona mais links à fila
        for link in soup.select("a[href]")[:5]:
            href = link.get("href")
            if href and href.startswith("http"):
                await crawler.add_requests([href])
    
    await crawler.run(["https://example.com"])

if __name__ == "__main__":
    asyncio.run(main())

Neste exemplo, cada sessão recebe um ID único que é incorporado ao username do proxy. O ProxyHat usa esse ID para retornar consistentemente o mesmo IP residencial enquanto a sessão estiver ativa. Quando um bloqueio é detectado, session.retire() descarta a sessão atual, e o Crawlee cria uma nova com um proxy diferente.

Usando curl para testar o proxy antes do crawl

# Testar proxy residencial com sessão fixa
curl -x http://seu_usuario-country-US-session-test01:sua_senha@gate.proxyhat.com:8080 \
  https://httpbin.org/ip

# Resposta esperada:
# { "origin": "198.x.x.x" }  # IP residencial dos EUA

# Testar SOCKS5 (quando HTTP não for suficiente)
curl -x socks5://seu_usuario-country-US-session-test01:sua_senha@gate.proxyhat.com:1080 \
  https://httpbin.org/ip

Integrando ProxyConfiguration ao SessionPool

O SessionPool do Crawlee gerencia o ciclo de vida das sessões. Cada sessão mantém cookies, headers e um proxy vinculado. A integração com ProxyConfiguration é automática quando você passa a configuração no construtor do crawler.

from crawlee.sessions import SessionPool
from crawlee.beautifulsoup_crawler import BeautifulSoupCrawler

proxy_config = ProxyHatProxyConfiguration()

# O SessionPool é gerenciado internamente pelo crawler.
# Mas você pode customizar parâmetros:
crawler = BeautifulSoupCrawler(
    proxy_configuration=proxy_config,
    max_session_rotations=10,        # máx de rotações antes de desistir
    max_request_retries=3,            # tentativas por requisição
    request_handler_timeout=30,       # timeout em segundos
    use_header_generator=True,        # gera headers aleatórios realistas
)

# O crawler cria sessões automaticamente e as vincula a proxies.
# Quando session.retire() é chamado, a sessão é descartada
# e uma nova é criada com um novo proxy do ProxyConfiguration.

O parâmetro max_session_rotations controla quantas vezes o Crawlee tentará rotacionar a sessão antes de marcar a requisição como falha. Para alvos protegidos, 10 rotações é um bom ponto de partida. Para sites sem anti-bot, 3 é suficiente.

Padrões de produção

1. Retirar sessões em bloqueios

O padrão mais importante: sempre chame session.retire() quando detectar um bloqueio. Isso garante que o IP problemático não seja reutilizado.

@crawler.router.default_handler
async def handler(request, soup, session):
    # Heurísticas de bloqueio
    blocked = False
    
    # Status 403/429 já tratados pelo framework, mas verifique conteúdo
    title = soup.find("title")
    if title:
        title_lower = title.text.lower()
        if any(kw in title_lower for kw in ["captcha", "blocked", "access denied"]):
            blocked = True
    
    # Cloudflare challenge page
    if soup.select_one("#challenge-form, #cf-challenge-running"):
        blocked = True
    
    # DataDome
    if soup.select_one("[data-detect], .dd-iframe"):
        blocked = True
    
    if blocked:
        session.retire()
        raise RuntimeError(f"Bloqueio detectado: {request.url}")
    
    # Processamento normal
    # ...

2. Configurar max_request_retries adequadamente

O max_request_retries define quantas vezes uma requisição será retentada antes de falhar permanentemente. Com rotação de proxy, cada retry usa uma nova sessão (e portanto um novo IP). Para alvos protegidos, use 3–5 retries. Para sites simples, 1–2 é suficiente.

3. Controlar concorrência via AutoscaledPool

O Crawlee ajusta automaticamente a concorrência com base na taxa de sucesso e latência. Mas você pode definir limites:

crawler = BeautifulSoupCrawler(
    proxy_configuration=proxy_config,
    max_requests_per_crawl=5000,
    max_request_retries=3,
    # AutoscaledPool controla concorrência dinamicamente
    # Limites sugeridos para proxies residenciais:
    min_concurrency=5,       # mínimo de requisições simultâneas
    max_concurrency=50,      # máximo (ajuste conforme seu plano ProxyHat)
    desired_concurrency=20,  # alvo inicial
)

Para proxies residenciais, mantenha a concorrência moderada. 50 requisições simultâneas com 100 sessões ativas é um bom equilíbrio para a maioria dos planos. Aumente gradualmente monitorando a taxa de sucesso.

4. Tratamento de erros no request_handler

Envolve a lógica de extração em try/except e use request.retry() para falhas transitórias:

@crawler.router.default_handler
async def handler(request, soup, session):
    try:
        # Extração de dados
        items = []
        for card in soup.select(".product-card"):
            items.append({
                "name": card.select_one(".name").text.strip(),
                "price": card.select_one(".price").text.strip(),
                "url": card.select_one("a[href]").get("href"),
            })
        
        # Salvar no Dataset
        from crawlee import Dataset
        dataset = await Dataset.open()
        await dataset.push_data(items)
        
    except AttributeError as e:
        # Seletor não encontrado — estrutura mudou
        print(f"Estrutura mudou em {request.url}: {e}")
        # Não retire a sessão — não é um bloqueio
        # Deixe o retry tentar novamente
        raise
    
    except Exception as e:
        # Erro inesperado — registra e continua
        print(f"Erro em {request.url}: {e}")
        raise

Quando NÃO usar browser crawling

PlaywrightCrawler é poderoso, mas caro. Cada instância consome ~200–300 MB de RAM e executa JavaScript completo. Use-o apenas quando:

  • O conteúdo é renderizado por JavaScript (React, Vue, Angular SPAs).
  • O anti-bot requer execução de challenges em JavaScript (Cloudflare Turnstile, DataDome challenge).
  • Você precisa interagir com a página (cliques, scroll, formulários).

Para tudo o resto — APIs JSON, HTML estático, feeds RSS, SERPs — BeautifulSoupCrawler com proxies residenciais é de 5x a 10x mais eficiente em custo e velocidade.

Escalando com containerização

Para escalar horizontalmente, containerize seus crawlers. Cada container executa uma instância do Crawlee com seu próprio SessionPool. Use um orquestrador (Kubernetes, Docker Swarm) para gerenciar réplicas.

# Dockerfile para crawler Crawlee
FROM python:3.12-slim

WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

# Variáveis de ambiente para ProxyHat
ENV PROXYHAT_USER=seu_usuario
ENV PROXYHAT_PASS=sua_senha

# Executa o crawler
CMD ["python", "crawler.py"]

Com 10 containers, cada um rodando 20 requisições concorrentes, você alcança 200 requisições simultâneas — tudo usando proxies residenciais do ProxyHat com rotação de sessão. Monitore a taxa de sucesso por container e ajuste a concorrência conforme necessário.

Configuração do ProxyHat

Para configurar seus proxies no ProxyHat, acesse o dashboard de preços para escolher o plano adequado e consulte os docs oficiais para detalhes de autenticação. O ProxyHat suporta geo-targeting por país e cidade, além de sessões fixas via parâmetro no username.

Para casos de uso específicos como web scraping e rastreamento de SERP, consulte nossas páginas dedicadas. A lista completa de localizações disponíveis ajuda a planejar a distribuição geográfica dos seus crawlers.

Considerações éticas e legais

Antes de qualquer crawl, verifique:

  • robots.txt: respeite as diretivas de Disallow. O Crawlee pode ser configurado para ler robots.txt automaticamente.
  • Termos de Serviço: alguns sites proíbem scraping nos ToS. Violar ToS pode ter consequências legais dependendo da jurisdição.
  • Rate limits: mesmo com proxies, respeite limites razoáveis. 1 requisição por segundo por domínio é um bom padrão para dados públicos.
  • Dados pessoais: a coleta de dados pessoais sem base legal pode violar o RGPD na UE e a CCPA na Califórnia.
  • APIs oficiais: se o site oferece uma API, use-a. É mais estável, legalmente mais segura e tecnicamente mais simples.

Principais takeaways

  • Use ProxyConfiguration com new_url(session_id=...) para fixar IPs residenciais por sessão — não rotacione a cada requisição quando precisar manter estado.
  • Integre o ProxyHat via gate.proxyhat.com:8080 (HTTP) ou :1080 (SOCKS5), com parâmetros de país e sessão no username.
  • Sempre chame session.retire() ao detectar bloqueios — isso força o Crawlee a criar uma nova sessão com um IP diferente.
  • Prefira BeautifulSoupCrawler para HTML estático; reserve PlaywrightCrawler para conteúdo dinâmico e anti-bot avançado.
  • Proxies residenciais têm ~95–99% de taxa de sucesso contra anti-bot, versus ~30–50% para datacenter em alvos protegidos.
  • Containerize e escale horizontalmente, mantendo 20–50 requisições concorrentes por container com proxies residenciais.

FAQ

O que é rotação de proxy no Crawlee para Python?

É o processo de distribuir requisições HTTP entre múltiplos IPs de proxy usando a classe ProxyConfiguration do Crawlee. A rotação pode ser round-robin (um IP por requisição) ou fixada por sessão (mesmo IP enquanto a sessão estiver ativa). O SessionPool gerencia o ciclo de vida das sessões, vinculando cookies e fingerprints a cada IP de proxy. Quando uma sessão é bloqueada, session.retire() descarta o IP e cria uma nova sessão com um proxy diferente.

Por que a rotação de proxy no Crawlee para Python é importante para usuários de proxy?

Sem rotação, um único IP fazendo centenas de requisições é rapidamente detectado por sistemas anti-bot como Cloudflare e DataDome. A rotação distribui o tráfego entre múltiplos IPs, reduzindo a probabilidade de bloqueio. Com proxies residenciais, cada IP parece tráfego orgânico de um dispositivo real, aumentando a taxa de sucesso de 30–50% (datacenter) para 95–99% em alvos protegidos. A integração nativa do Crawlee com ProxyConfiguration automatiza esse processo sem código boilerplate.

Qual tipo de proxy funciona melhor para rotação no Crawlee para Python?

Proxies residenciais são a melhor escolha para a maioria dos casos de uso. Eles usam IPs de dispositivos reais em ISPs legítimos, tornando o tráfego indistinguível de navegação orgânica. Proxies mobile (4G/5G) são ainda mais confiáveis para anti-bot agressivo, mas têm custo mais alto. Proxies datacenter são adequados apenas para endpoints sem proteção anti-bot — são rápidos e baratos, mas facilmente bloqueados. A estratégia ideal é em camadas: residencial primeiro, mobile como fallback, datacenter como último recurso.

Como evitar bloqueios ao implementar rotação de proxy no Crawlee para Python?

Use quatro estratégias combinadas: (1) proxies residenciais com sessões fixas via new_url(session_id=...) para manter estado; (2) session.retire() imediato ao detectar CAPTCHAs, páginas de challenge ou status 403/429; (3) max_request_retries=3 para que requisições bloqueadas sejam retentadas com novos IPs; (4) concorrência moderada (20–50 requisições simultâneas) via AutoscaledPool. Adicione rotação de user-agent com use_header_generator=True e respeite rate limits razoáveis.

Como integrar o ProxyHat com o ProxyConfiguration do Crawlee?

Crie uma subclasse de ProxyConfiguration que sobrescreve new_url() retornando URLs no formato http://USUÁRIO-country-US-session-ID:SENHA@gate.proxyhat.com:8080. O parâmetro session-ID no username garante que o ProxyHat retorne o mesmo IP residencial enquanto a sessão estiver ativa. Para SOCKS5, use a porta 1080 no lugar de 8080. Passe a configuração personalizada no parâmetro proxy_configuration do crawler.

Perguntas frequentes

O que é rotação de proxy no Crawlee para Python?

É o processo de distribuir requisições HTTP entre múltiplos IPs de proxy usando a classe ProxyConfiguration do Crawlee. A rotação pode ser round-robin (um IP por requisição) ou fixada por sessão (mesmo IP enquanto a sessão estiver ativa). O SessionPool gerencia o ciclo de vida das sessões, vinculando cookies e fingerprints a cada IP de proxy. Quando uma sessão é bloqueada, session.retire() descarta o IP e cria uma nova sessão com um proxy diferente.

Por que a rotação de proxy no Crawlee para Python é importante para usuários de proxy?

Sem rotação, um único IP fazendo centenas de requisições é rapidamente detectado por sistemas anti-bot como Cloudflare e DataDome. A rotação distribui o tráfego entre múltiplos IPs, reduzindo a probabilidade de bloqueio. Com proxies residenciais, cada IP parece tráfego orgânico de um dispositivo real, aumentando a taxa de sucesso de 30–50% (datacenter) para 95–99% em alvos protegidos.

Qual tipo de proxy funciona melhor para rotação no Crawlee para Python?

Proxies residenciais são a melhor escolha para a maioria dos casos de uso. Eles usam IPs de dispositivos reais em ISPs legítimos, tornando o tráfego indistinguível de navegação orgânica. Proxies mobile (4G/5G) são ainda mais confiáveis para anti-bot agressivo, mas têm custo mais alto. Proxies datacenter são adequados apenas para endpoints sem proteção anti-bot. A estratégia ideal é em camadas: residencial primeiro, mobile como fallback, datacenter como último recurso.

Como evitar bloqueios ao implementar rotação de proxy no Crawlee para Python?

Use quatro estratégias combinadas: (1) proxies residenciais com sessões fixas via new_url(session_id=...) para manter estado; (2) session.retire() imediato ao detectar CAPTCHAs, páginas de challenge ou status 403/429; (3) max_request_retries=3 para que requisições bloqueadas sejam retentadas com novos IPs; (4) concorrência moderada (20–50 requisições simultâneas) via AutoscaledPool. Adicione rotação de user-agent com use_header_generator=True e respeite rate limits razoáveis.

Como integrar o ProxyHat com o ProxyConfiguration do Crawlee?

Crie uma subclasse de ProxyConfiguration que sobrescreve new_url() retornando URLs no formato http://USUÁRIO-country-US-session-ID:SENHA@gate.proxyhat.com:8080. O parâmetro session-ID no username garante que o ProxyHat retorne o mesmo IP residencial enquanto a sessão estiver ativa. Para SOCKS5, use a porta 1080 no lugar de 8080. Passe a configuração personalizada no parâmetro proxy_configuration do crawler.

Pronto para começar?

Proxies residenciais, ISP e móveis em mais de 148 países. Crie uma conta grátis.

Criar conta grátis
← Voltar ao Blog