Voltar ao blogue
Guias
Raluca PenciucLast updated on May 8, 202611 min read

Como rodar proxies em Python

Como rodar proxies em Python
Resumo: Este guia mostra como alternar entre proxies em Python de ponta a ponta: escolher o tipo de proxy adequado, criar e validar um conjunto de proxies e, em seguida, alternar sequencialmente com itertools.cycle, aleatoriamente com random.choiceou de forma assíncrona com aiohttp. Também combinamos a rotação de IP com a rotação de User-Agent e adicionamos tentativas de repetição sensíveis ao estado, para que um único proxy defeituoso não comprometa a sua tarefa de scraping.

Se o seu scraper em Python começou a devolver erros 403, 429 ou páginas vazias depois de ter funcionado bem ontem, é quase certo que está a ser limitado ou banido por IP. A solução a que a maioria das equipas recorre é a rotação de proxies, e aprender a rodar proxies em Python é um ritual de passagem para quem quer ir além de um script de hobby.

A rotação de proxies em Python significa alterar o IP de saída por pedido, de forma programada ou aleatória, para que cada pedido pareça ter vindo de uma máquina diferente. Bem feita, distribui a carga por muitos IPs, contorna os limites de taxa por IP e torna o tráfego do scraper mais difícil de identificar pelos sistemas anti-bot. Mal feita, com uma lista de IPs livres desatualizada e uma abordagem genérica try/except, acaba por transformar um IP banido num conjunto de IPs banidos.

Este artigo é a versão prática de como rodar proxies em Python. Iremos escolher tipos de proxy, construir um conjunto validado, enviar uma solicitação através do Requests e, em seguida, percorrer três estratégias de rotação (sequencial, aleatória, assíncrona). Iremos combinar a rotação de IP com a rotação de cabeçalhos, adicionar um tratamento de erros real e terminar com uma comparação honesta entre comprar e construir.

O que é a rotação de proxies e por que o seu scraper Python precisa dela

Um proxy oculta o seu IP real por trás de um IP intermediário, mas um único proxy estático continua a ser um IP que um alvo pode limitar e banir. A rotação de proxies troca o IP de saída por pedido ou por sessão, de modo que o mesmo scraper parece vir de várias origens.

Isto é importante porque os sistemas anti-bot dependem fortemente da limitação de taxa, limitando as solicitações por IP num determinado intervalo antes de responder com 429s. A rotação num conjunto saudável mantém cada IP abaixo desses limites e impede que um único banimento acabe com todo o trabalho.

Escolha o tipo de proxy certo antes de fazer a rotação

A rotação só é eficaz na medida em que os IPs que se utilizam o são. Escolher o tipo errado é a razão pela qual as equipas desperdiçam semanas a ajustar a lógica contra um alvo que nunca aceitaria o seu tráfego.

Tipo de proxy

Velocidade

Risco de bloqueio

Custo

Ideal para

Centro de dados

Mais rápido

Excelente em sites protegidos

Mais baixo

APIs públicas, defesas reduzidas

Residencial

Médio

Baixo

Médio-alto

Comércio eletrónico, SERPs, páginas com segmentação geográfica

Móvel (4G/5G)

Mais lento

Mais baixo

Mais alto

Redes sociais, APIs de aplicações, alvos específicos

ISP (residencial estático)

Rápido

Baixa

Médio-alto

Sessões longas, scraping de contas

A primeira decisão sobre como rodar proxies em Python não é o algoritmo; é adequar o conjunto de proxies à defesa.

Configure o seu ambiente Python para rotação de proxies

Use Python 3.8+ num virtualenv. Instale o Requests e aiohttpe mantenha os proxies num ficheiro de texto simples para que o rotador os possa recarregar em tempo real.

mkdir proxy_rotator && cd proxy_rotator
python -m venv .venv && source .venv/bin/activate
pip install requests aiohttp
touch app.py proxies.txt

Crie e valide uma lista de proxies funcional

Podes compilar uma proxies.txt a partir de fontes públicas (agregadores de proxies gratuitos, espelhos do GitHub) ou carregar credenciais de um conjunto pago. Seja como for, espere que uma parte significativa esteja inativa antes da sua primeira solicitação, especialmente em listas gratuitas, onde a maioria das entradas pode já estar bloqueada por destinos populares.

Use uma entrada por linha, no formato http://host:port ou http://user:pass@host:port, e depois valida-a contra um ponto final de eco de IP:

import requests

def validate(proxy, timeout=5):
    try:
        r = requests.get("https://httpbin.io/ip",
                         proxies={"http": proxy, "https": proxy},
                         timeout=timeout)
        return r.ok and proxy.split("@")[-1].split(":")[0] in r.text
    except requests.RequestException:
        return False

with open("proxies.txt") as f:
    pool = [p.strip() for p in f if p.strip() and validate(p.strip())]

A verificação de correspondência de IP deteta proxies transparentes que deixam passar o seu endereço real. Para verificações mais aprofundadas, faça um ping a uma página de destino real em vez de apenas httpbin.io/ip.

Enviar uma única solicitação através de um proxy com Requests

Antes de rodar qualquer coisa, certifique-se de que um proxy funciona de ponta a ponta. O Requests aceita um proxies dicionário em get() ou em um Session; a mesma URL geralmente funciona para ambos http e https chaves.

import requests

proxy = "http://user:pass@host:port"   # auth is embedded in the URL
proxies = {"http": proxy, "https": proxy}

with requests.Session() as s:
    s.proxies.update(proxies)
    r = s.get("https://httpbin.io/ip", timeout=10)
    print(r.status_code, r.json())

Se preferir manter a configuração do proxy fora do código, defina o HTTP_PROXY e HTTPS_PROXY ; o Requests lê-as automaticamente. Os proxies gratuitos costumam gerar SSLError: CERTIFICATE_VERIFY_FAILED porque interceptam o TLS. Como solução temporária, pode passar verify=False, mas trate isso como uma ferramenta de depuração, não como uma configuração de produção, uma vez que desativa totalmente a validação do certificado.

Como alternar proxies em Python: três estratégias (sequencial, aleatória e assíncrona)

Assim que uma única solicitação funcionar, a questão de como rodar proxies em Python torna-se um equilíbrio entre previsibilidade, discrição e rendimento. Os três padrões abaixo abrangem quase todos os scrapers reais.

Rotação sequencial com itertools.cycle

A rotação sequencial percorre o conjunto de IPs por ordem e volta ao início, distribuindo o tráfego uniformemente. É o padrão mais fácil de compreender, porque o próximo IP é sempre previsível.

import itertools, requests

with open("proxies.txt") as f:
    proxies = [p.strip() for p in f if p.strip()]

pool = itertools.cycle(proxies)

for _ in range(8):
    proxy = next(pool)
    r = requests.get("https://httpbin.io/ip",
                     proxies={"http": proxy, "https": proxy},
                     timeout=10)
    print(proxy, r.status_code)

A desvantagem é que uma ordem determinística é, por si só, uma assinatura digital. Se um defensor vir os IPs A, B, C, D, A, B, C, D a partir da mesma assinatura digital do navegador em poucos segundos, pode sinalizar todo o conjunto. A rotação sequencial funciona melhor em conjuntos maiores com atrasos mais longos por IP.

Rotação aleatória com random.choice

A rotação aleatória quebra o padrão ao escolher um proxy arbitrário em cada pedido, o que torna o tráfego mais difícil de correlacionar.

import random, requests

with open("proxies.txt") as f:
    proxies = [p.strip() for p in f if p.strip()]

for _ in range(8):
    proxy = random.choice(proxies)
    r = requests.get("https://httpbin.io/ip",
                     proxies={"http": proxy, "https": proxy},
                     timeout=10)
    print(proxy, r.status_code)

A desvantagem é a utilização desigual: um conjunto pequeno irá sobreutilizar alguns IPs e deixar outros inativos. Para um melhor equilíbrio, faça o sorteio sem reposição até que o conjunto se esgote utilizando random.sample(proxies, len(proxies)) e, em seguida, reorganize. Isso mantém as solicitações imprevisíveis, ao mesmo tempo que distribui a carga.

Rotação assíncrona com aiohttp e asyncio

Quando o seu conjunto ultrapassa algumas dezenas de IPs, a sua validação em série torna-se o gargalo. A rotação assíncrona executa muitas solicitações simultaneamente numa única thread, o que reduz drasticamente o tempo de validação e permite que um conjunto de trabalhadores processe uma lista de tarefas sem ficar bloqueado em proxies lentos.

import asyncio, aiohttp

CONCURRENCY = 20
TIMEOUT = aiohttp.ClientTimeout(total=10)

async def check_proxy(session, proxy, sem):
    async with sem:
        try:
            async with session.get("https://httpbin.io/ip",
                                   proxy=proxy, timeout=TIMEOUT) as r:
                return proxy, r.status, await r.text()
        except (aiohttp.ClientError, asyncio.TimeoutError) as e:
            return proxy, None, str(e)

async def main(proxies):
    sem = asyncio.Semaphore(CONCURRENCY)
    async with aiohttp.ClientSession() as session:
        tasks = [check_proxy(session, p, sem) for p in proxies]
        return await asyncio.gather(*tasks)

with open("proxies.txt") as f:
    proxies = [p.strip() for p in f if p.strip()]
results = asyncio.run(main(proxies))

O semáforo limita o número de pedidos que podem ser enviados de uma só vez, para que não esgote os descritores de ficheiros nem ultrapasse os limites de pico do destino. aiohttp expõe um argumento por solicitação proxy= , que a documentação do cliente avançado do aiohttp aborda em detalhe, juntamente com o comportamento de autenticação e do ambiente de confiança.

Combine a rotação de proxies com a rotação de User-Agent e cabeçalhos

A rotação de IPs por si só ainda revela uma impressão digital. Se 200 IPs diferentes enviarem o mesmo python-requests/2.31.0 , um sistema anti-bot pode correlacioná-los instantaneamente.

Alterne cabeçalhos juntamente com proxies e mantenha os cookies vinculados à identidade que os definiu:

import random

UAS = [
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ...",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 13_5) AppleWebKit/605.1.15 ...",
    "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 ...",
]
LANGS = ["en-US,en;q=0.9", "en-GB,en;q=0.8", "de-DE,de;q=0.9,en;q=0.8"]

def rotated_headers():
    return {"User-Agent": random.choice(UAS),
            "Accept-Language": random.choice(LANGS),
            "Referer": "https://www.google.com/"}

Vincule um User-Agent e um conjunto de cookies a um proxy durante a duração de uma sessão lógica e, em seguida, rode-os em conjunto quando mudar de identidade.

Tratamento de erros de nível de produção e verificações de integridade do proxy

A maioria dos utilizadores iniciantes descarta um proxy ao primeiro erro. Isso desperdiça IPs que estavam apenas limitados em termos de taxa e trata um proxy avariado da mesma forma que um alvo a pedir-lhe para abrandar.

Trate o código de resposta como um sinal. De acordo com a RFC 6585, 429 significa demasiados pedidos, não um proxy inoperante: afaste-se e tente novamente com o mesmo IP. Desista em caso de 407 ou erros de ligação repetidos e coloque os proxies defeituosos em quarentena para que possa verificá-los novamente após um período de espera.

import time, random
from collections import defaultdict

class ProxyManager:
    def __init__(self, proxies, max_fail=3, cooldown=300):
        self.live, self.dead = list(proxies), {}
        self.fails = defaultdict(int)
        self.max_fail, self.cooldown = max_fail, cooldown

    def get(self):
        self._revive()
        return random.choice(self.live) if self.live else None

    def report(self, proxy, status=None, error=None):
        if status == 429 or (status and 500 <= status < 600):
            time.sleep(min(2 ** self.fails[proxy], 30))   # keep, back off
        elif status == 407 or error:
            self.fails[proxy] += 1
            if self.fails[proxy] >= self.max_fail:
                self.live.remove(proxy)
                self.dead[proxy] = time.time() + self.cooldown

    def _revive(self):
        now = time.time()
        for p, t in list(self.dead.items()):
            if now >= t:
                self.live.append(p); self.dead.pop(p); self.fails[p] = 0

Ajuste max_fail e o atraso base de acordo com o seu perfil de tráfego, em vez de copiar cegamente os valores predefinidos.

Rotação manual vs. rotação gerida: escolher o seu caminho

Criar o seu próprio rotador é adequado para aprendizagem e tarefas pequenas. Em grande escala, torna-se um segundo produto: rotatividade de proxies, validadores, novas tentativas e plantão quando um alvo atualiza a sua pilha.

Um proxy rotativo gerido ou uma API Scraper oculta tudo isso por trás de um único ponto de extremidade e cobra por cada pedido bem-sucedido.

Signal

Lean DIY

Gestão enxuta

Tamanho do pool

< 100 IPs

Milhares+

Dificuldade do alvo

Defesa reduzida

Marketplaces, SERPs, redes sociais

Necessidades de SLA

Melhor esforço

Taxa de sucesso previsível

O objetivo de aprender a rodar proxies em Python não é manter um rotador para sempre; é saber quando a rotação manual é suficiente e quando delegar.

Pontos-chave

  • Combine o tipo de proxy com o destino antes de ajustar a lógica de rotação; rodar IPs de centros de dados baratos contra um site fortificado é uma batalha perdida.
  • Uma configuração fiável de rotação de proxies em Python começa com um conjunto de proxies validados, não com uma lista aleatória, e volta a verificar os proxies inativos após um período de espera, porque os conjuntos livres alternam entre estados ativos e inativos.
  • Utilize itertools.cycle para uma distribuição previsível, random.choice para discrição e aiohttp com asyncio para validação de alto rendimento e recuperações simultâneas.
  • Alterne os valores de User-Agent e cabeçalhos juntamente com os IPs para não revelar uma assinatura digital estável por trás de 200 proxies diferentes.
  • Crie um rotador sensível ao estado que recue em 429 e 5xx, desista em 407 ou erros de ligação repetidos e coloque em quarentena proxies maliciosos, em vez de tratar todas as exceções da mesma forma.

Perguntas frequentes

Qual é a diferença entre rodar proxies por conta própria e usar um gateway de proxies rotativos ou uma API de scraping?

Criar o seu próprio rotador significa que é o proprietário da lista de proxies, da validação, da lógica de repetição de tentativas e do encaminhamento geográfico. Um gateway de proxies rotativos expõe um único ponto de extremidade que seleciona um IP por si em cada pedido, enquanto uma API de scraping também lida com a renderização do navegador, CAPTCHAs e desbloqueio. O «faça você mesmo» dá-lhe o máximo controlo; os gateways e as APIs trocam algum controlo por muito menos código de infraestrutura.

De quantos proxies preciso no meu conjunto de rotação para um trabalho típico de scraping?

Uma regra prática útil é um IP ativo por trabalhador simultâneo, mais 5 a 10 vezes mais em reserva para absorver rotatividade, bloqueios e proxies inativos. Trabalhos pequenos com alguns milhares de pedidos podem ser executados em 20 a 50 IPs residenciais verificados; scrapes que atingem alvos fortificados ou milhões de páginas normalmente precisam de milhares de IPs rotativos para manter baixas as taxas de pedidos por IP.

Por que razão os proxies gratuitos continuam a ser bloqueados mesmo quando os alterno em cada pedido?

Os proxies gratuitos são partilhados por muitos desconhecidos que executam os seus próprios scrapers, pelo que os IPs geralmente já estão na lista negra de alvos populares antes mesmo de os utilizar. Também apresentam fugas de forma óbvia, enviando cabeçalhos como Via ou X-Forwarded-For, não correspondendo ao IP que alegam ou violando o TLS. A rotação não consegue corrigir um IP que já está na lista de bloqueios.

Devo alternar proxies em cada pedido ou manter uma sessão fixa por site de destino?

Utilize sessões persistentes sempre que o alvo vincule o estado a um IP, como páginas de início de sessão, checkouts em várias etapas ou fluxos com uso intensivo de JavaScript que emitem muitas sub-solicitações. Alterne por solicitação ao extrair listagens sem estado, páginas de pesquisa ou feeds de produtos. Um padrão comum é um IP por sessão lógica, seguido de um IP novo para a sessão seguinte.

Posso reutilizar este padrão de rotação com o Selenium ou o Playwright em vez do Requests?

Sim, com alguns ajustes. Ambas as ferramentas de automação de navegadores aceitam configurações de proxy, mas normalmente tem de iniciar um contexto de navegador por proxy, porque a maioria dos drivers não permite alterar o proxy a meio da sessão. Crie um conjunto de navegadores de trabalho, cada um associado a um IP e a um User-Agent, e alterne os próprios navegadores de trabalho em vez da variável de proxy dentro de um único navegador.

Conclusão: da rotação manual à extração fiável

Saber como rodar proxies em Python é uma competência fundamental para qualquer programador que pretenda ir além de um scraper de IP único. Agora já tem os alicerces: escolha o tipo de proxy certo para o seu alvo, valide o conjunto antes de confiar nele, rode sequencialmente, aleatoriamente ou de forma assíncrona, dependendo das suas prioridades, incorpore a rotação de User-Agent e utilize um gestor sensível ao estado para que um único 429 não comprometa um IP saudável.

O que é mais difícil é manter tudo a funcionar corretamente contra alvos que alteram as suas defesas sem aviso prévio. As listas gratuitas deterioram-se, os conjuntos residenciais precisam de reequilíbrio e as regras 429 variam. Se preferir dedicar esse tempo de engenharia aos dados e não à infraestrutura, a API de Scraper da WebScrapingAPI gere a rotação de proxies, a evasão anti-bot e as tentativas de repetição por trás de um único ponto de extremidade, para que possa manter o seu código Requests ou aiohttp código e apenas trocar a camada de obtenção de dados. Faça você mesmo a rotação de IPs para aprendizagem ou tarefas pequenas e recorra a uma camada gerida quando os custos de manutenção ultrapassarem as poupanças.

Sobre o autor
Raluca Penciuc, Desenvolvedor Full-Stack @ WebScrapingAPI
Raluca PenciucDesenvolvedor Full-Stack

Raluca Penciuc é programadora Full Stack na WebScrapingAPI, onde desenvolve scrapers, aperfeiçoa estratégias de evasão e procura formas fiáveis de reduzir a deteção nos sites-alvo.

Comece a construir

Pronto para expandir a sua recolha de dados?

Junte-se a mais de 2.000 empresas que utilizam a WebScrapingAPI para extrair dados da Web à escala empresarial, sem quaisquer custos de infraestrutura.