Socks5Proxy

Configuração de proxy no Scrapy: usar IPs diferentes por requisição com meta proxy

Este guia mostra como conectar proxies HTTP da Socks5Proxy no Scrapy via meta proxy, middleware para rotacionar IPs da API por requisição, e configuração de velocidade adaptada ao site alvo.

Como o Scrapy lida com proxies?

O Scrapy tem HttpProxyMiddleware ativado por padrão. Adicione o endereço do proxy ao dicionário meta da requisição com a chave proxy, e o middleware converterá o nome de usuário e senha no cabeçalho Proxy-Authorization. URLs HTTPS passam por um túnel CONNECT.

O handler de download padrão do Scrapy suporta proxies HTTP. Se SOCKS5 for essencial, será necessário um handler personalizado, por isso recomendamos usar a porta HTTP do mesmo IP no Scrapy. O IP visto pelo site de destino será o mesmo.

O exemplo usa IP 198.51.100.23, porta HTTP 8000, nome de usuário spx_user e senha spx_pass.

pip install scrapy
scrapy startproject shop
cd shop

Como adicionar um proxy a uma solicitação?

Adicione proxy ao meta de Request em start_requests. Repita o processo para requisições subsequentes nos callbacks. Para manter a sessão, passe o valor proxy do meta da resposta anterior.

import scrapy

PROXY = "http://spx_user:spx_pass@198.51.100.23:8000"

class IpCheckSpider(scrapy.Spider):
    name = "ip_check"

    def start_requests(self):
        yield scrapy.Request("https://api.ipify.org?format=json", meta={"proxy": PROXY})

    def parse(self, response):
        self.logger.info("seen as %s", response.json()["ip"])

Como rotacionar IPs a cada solicitação?

Crie um middleware de download para adicionar o próximo proxy a todas as solicitações, permitindo a rotação sem alterar o código do spider. O middleware abaixo recebe a lista via API ao iniciar e mantém o proxy na meta se já estiver presente, permitindo o uso combinado de sessão fixa e rotação.

Armazene chaves API em settings.py ou leia de variáveis de ambiente. Registre com número menor que HttpProxyMiddleware(750) para que o middleware base processe os endereços inseridos.

import itertools
import requests

class RotatingProxyMiddleware:
    def __init__(self, key):
        text = requests.get(
            "https://socks5proxy.io/api/v1/proxies/download",
            params={"format": "user:pass@ip:port", "protocol": "http"},
            headers={"Authorization": "Bearer " + key},
            timeout=30,
        ).text
        self.pool = itertools.cycle(["http://" + l.strip() for l in text.splitlines() if l.strip()])

    @classmethod
    def from_crawler(cls, crawler):
        return cls(crawler.settings.get("SPX_API_KEY"))

    def process_request(self, request, spider):
        if "proxy" not in request.meta:  # keep a proxy that was set on purpose (sticky sessions)
            request.meta["proxy"] = next(self.pool)

Como ajustar velocidade e tentativas?

CONCURRENT_REQUESTS_PER_DOMAIN define requisições simultâneas para o mesmo domínio. Com mais proxies, você pode aumentar este valor mantendo a carga por IP. Por exemplo, 500 IPs com 50 requisições simultâneas usam cada IP em média apenas 1 vez a cada 10 requisições.

AUTOTHROTTLE ajusta automaticamente intervalos entre requisições conforme a velocidade de resposta. Para muitos erros 429, use RETRY_HTTP_CODES para tentar novamente, removendo o proxy do meta para que o middleware tente o próximo proxy.

Inclua uma etapa para verificar se os resultados são páginas reais, não telas de confirmação. Se elementos esperados estiverem faltando, reenvie a requisição por outro IP.

  • Ajuste requisições simultâneas por domínio conforme número de IPs
  • AUTOTHROTTLE ajusta intervalos conforme velocidade de resposta
  • Para erros 429 e 5xx, tente novamente com outro IP
  • Filtrar CAPTCHAs via inspeção de conteúdo

O que muda com autorização por IP?

Registre o IPv4 do servidor Scrapy no dashboard para usar meta proxy sem credenciais, como http://198.51.100.23:8000. Você também pode baixar listas no formato ip:port. Se usar vários servidores, registre todos os IPs (até 10).

Como agrupar requisições com sessão no mesmo IP?

Para fluxos que exigem continuidade de cookies, como login ou carrinho de compras, é necessário usar o mesmo IP. Insira o meta proxy diretamente na primeira solicitação e passe o valor de proxy de response.meta para a próxima solicitação no callback, para que o middleware de ciclo não o altere. Usar a chave meta cookiejar do Scrapy também ajuda a separar os cookies por sessão.

Vinculando um proxy e cookies a cada sessão, múltiplas sessões podem operar simultaneamente sem interferência.

import scrapy

PROXIES = [
    "http://spx_user:spx_pass@198.51.100.23:8000",
    "http://spx_user:spx_pass@198.51.100.24:8000",
]

class SessionSpider(scrapy.Spider):
    name = "sessions"

    def start_requests(self):
        for i, proxy in enumerate(PROXIES):
            yield scrapy.Request("https://example.com/", meta={"proxy": proxy, "cookiejar": i}, dont_filter=True)

    def parse(self, response):
        # follow-up request keeps the same proxy and the same cookie jar
        yield response.follow("/account", meta={"proxy": response.meta["proxy"], "cookiejar": response.meta["cookiejar"]}, callback=self.parse_account)

    def parse_account(self, response):
        self.logger.info("status %s via %s", response.status, response.meta["proxy"])

Como remover temporariamente um proxy com falha?

No middleware, se você receber uma resposta 403 ou 429 no process_response, pode pausar o uso desse proxy por alguns minutos e enviar a mesma solicitação através de outro proxy. Copie a solicitação, remova o proxy do meta, ative dont_filter e retorne para que o próximo proxy seja usado.

Gerencie listas de proxies em pausa e horários de reutilização em um dicionário. Evitar reuso imediato do mesmo IP dá tempo para limites do site serem resetados.

Quais configurações economizam largura de banda no Scrapy?

O Scrapy recebe apenas HTML por padrão, consumindo muito menos largura de banda que ferramentas baseadas em navegador. Com o HttpCompressionMiddleware ativado por padrão para respostas compactadas, o volume de dados é ainda menor. Por isso, é possível coletar muitas páginas mesmo dentro da largura de banda mensal de planos compartilhados.

Ative HTTPCACHE_ENABLED durante o desenvolvimento para evitar requisições repetidas ao mesmo site. Em produção, mantenha a filtragem de URLs duplicados (ativada por padrão) e use dont_filter apenas para requisições que precisam ser refeitas.

Também é importante limitar o escopo de links seguidos para evitar navegar em subpáginas desnecessárias. Definir claramente o escopo da coleta reduz tempo, largura de banda e a carga no site alvo.

Como resolver problemas frequentes?

Se receber resposta 407, verifique o nome de usuário e senha no endereço. Se a senha tiver caracteres especiais, codifique-os com percent-encoding. TunnelError ocorre quando o proxy não aceita requisições CONNECT - confira se está usando a porta HTTP.

Se todas as solicitações forem feitas pelo mesmo IP, pode ser que o middleware esteja após o HttpProxyMiddleware ou que o spider esteja inserindo meta proxy diretamente. Verifique a ordem no settings.py e o código do spider.

Configuração de proxy no Scrapy: meta proxy e middleware de rotação | Socks5Proxy