Voltar ao blog

Como configurar proxy no Python requests para scraping, API e automação: guia completo com exemplos de código

Guia completo para conectar proxies na biblioteca Python requests — desde a configuração básica até a rotação de IP e contorno de bloqueios ao fazer scraping e automação.

📅3 de abril de 2026
```html

Se seu script em Python está recebendo um erro 403, CAPTCHA ou banimento por IP — isso significa que o site alvo já notou você. Conectar um proxy à biblioteca requests resolve esse problema: você muda o endereço IP, contorna restrições geográficas e distribui a carga entre vários endereços. Neste guia — tudo, desde a conexão básica até a rotação avançada com exemplos de código reais.

Por que usar proxies em scripts Python

A maioria dos sites e APIs rastreia os endereços IP das solicitações recebidas. Se um único endereço faz mais de 100 solicitações por minuto — ele é bloqueado. Essa é uma proteção padrão contra bots, utilizada por Wildberries, Ozon, Avito, Google, Instagram e centenas de outras plataformas. O proxy permite que você direcione a solicitação através de um servidor intermediário com um endereço IP diferente, tornando você invisível para os sistemas de proteção.

Aqui estão as principais tarefas onde proxies em Python são criticamente necessários:

  • Scraping de marketplaces — coleta de preços de Wildberries, Ozon, Yandex.Market sem bloqueios por IP
  • Monitoramento de concorrentes — solicitações regulares aos sites dos concorrentes a cada 5–15 minutos
  • Trabalho com APIs com limites — distribuição de solicitações entre vários IPs para não exceder o limite de taxa
  • Teste de geolocalização — verificação de como o site aparece de diferentes países e regiões
  • Automatização de formulários e registros — criação de contas ou preenchimento de formulários de diferentes IPs
  • Monitoramento de SEO — coleta de posições de diferentes regiões da Rússia e outros países

Sem proxies, mesmo um parser bem escrito encontrará bloqueios após algumas horas de operação. Com uma rotação de IPs corretamente configurada, o mesmo script funciona por semanas sem interrupções.

Configuração básica de proxy em requests

A biblioteca requests suporta proxies nativamente — nenhum pacote adicional é necessário. O proxy é passado através de um dicionário proxies nos parâmetros da solicitação.

O exemplo mais simples — proxy HTTP para uma única solicitação:

import requests

proxies = {
    "http": "http://123.45.67.89:8080",
    "https": "http://123.45.67.89:8080",
}

response = requests.get("https://httpbin.org/ip", proxies=proxies)
print(response.json())
# {'origin': '123.45.67.89'}
  

Note que: no dicionário proxies você deve especificar ambas as chaves — http e https. Se você especificar apenas uma, as solicitações do segundo protocolo irão diretamente sem proxy. Este é um erro comum entre iniciantes, que resulta na fuga do IP real.

Para garantir que o proxy está funcionando, use o serviço httpbin.org/ip — ele retorna o endereço IP de onde a solicitação foi feita. Se na resposta você vê o IP do servidor proxy, e não o seu — tudo está configurado corretamente.

Proxies HTTP, HTTPS e SOCKS5: diferenças e exemplos de código

Existem diferentes tipos de proxies, e cada um é adequado para suas tarefas. No contexto de Python requests, é importante entender a diferença entre os três principais protocolos:

Tipo Protocolo na URL Velocidade Suporte a UDP Melhor cenário
HTTP http:// Alta Não Scraping de sites HTTP
HTTPS https:// Alta Não Scraping de sites seguros
SOCKS5 socks5:// Média Sim Anonimato completo, qualquer protocolo

Para trabalhar com SOCKS5 em Python, é necessário instalar um pacote adicional:

pip install requests[socks]
# ou separadamente:
pip install PySocks
  

Após a instalação, a conexão com o proxy SOCKS5 fica assim:

import requests

# Proxy SOCKS5
proxies = {
    "http": "socks5://123.45.67.89:1080",
    "https": "socks5://123.45.67.89:1080",
}

response = requests.get("https://httpbin.org/ip", proxies=proxies)
print(response.json())
  

SOCKS5 é o protocolo preferido para tarefas onde a anonimidade é importante. Ao contrário do proxy HTTP, o SOCKS5 não adiciona cabeçalhos X-Forwarded-For, que podem revelar seu IP real.

Proxy com autenticação por login e senha

A maioria dos serviços de proxy pagos utiliza autenticação por login e senha. Essa é uma prática padrão — sem autorização, o proxy simplesmente não permitirá sua solicitação. Na biblioteca requests, os dados de autenticação são passados diretamente na URL do proxy.

import requests

# Formato: protocolo://login:senha@host:porta
proxy_url = "http://myuser:[email protected]:8080"

proxies = {
    "http": proxy_url,
    "https": proxy_url,
}

response = requests.get("https://httpbin.org/ip", proxies=proxies)
print(response.status_code)
print(response.json())
  

Se a senha ou o login contiver caracteres especiais (por exemplo, @, #, %), eles precisam ser codificados em URL. Para isso, use o módulo urllib.parse:

import requests
from urllib.parse import quote

username = "myuser"
password = "p@ss#word!"  # Caracteres especiais

# URL codificando login e senha
encoded_user = quote(username, safe="")
encoded_pass = quote(password, safe="")

proxy_url = f"http://{encoded_user}:{encoded_pass}@123.45.67.89:8080"

proxies = {
    "http": proxy_url,
    "https": proxy_url,
}

response = requests.get("https://httpbin.org/ip", proxies=proxies)
print(response.json())
  

💡 Dica de segurança

Nunca hardcode o login e a senha diretamente no código do script. Use variáveis de ambiente ou um arquivo .env com a biblioteca python-dotenv. Assim, você evita a possível exposição de credenciais ao publicar o código no GitHub.

Rotação de proxies: troca automática de IP para scraping

Um proxy — ainda é um único endereço IP, que pode ser bloqueado. A verdadeira proteção contra bans é a rotação: cada solicitação (ou a cada N solicitações) sai com um novo IP. Abaixo estão algumas abordagens para implementar a rotação.

Método 1: Seleção aleatória da lista

import requests
import random

# Lista de proxies
proxy_list = [
    "http://user:[email protected]:8080",
    "http://user:[email protected]:8080",
    "http://user:[email protected]:8080",
    "http://user:[email protected]:8080",
]

def get_random_proxy():
    proxy = random.choice(proxy_list)
    return {"http": proxy, "https": proxy}

# Scraping de 10 páginas com rotação de IP
urls = [f"https://example.com/page/{i}" for i in range(1, 11)]

for url in urls:
    proxies = get_random_proxy()
    try:
        response = requests.get(url, proxies=proxies, timeout=10)
        print(f"URL: {url} | IP: {proxies['http'].split('@')[1]} | Status: {response.status_code}")
    except requests.RequestException as e:
        print(f"Erro: {e}")
  

Método 2: Rotação cíclica através de itertools

import requests
import itertools

proxy_list = [
    "http://user:[email protected]:8080",
    "http://user:[email protected]:8080",
    "http://user:[email protected]:8080",
]

# Criando um ciclo infinito pela lista de proxies
proxy_cycle = itertools.cycle(proxy_list)

def get_next_proxy():
    proxy = next(proxy_cycle)
    return {"http": proxy, "https": proxy}

# Cada solicitação usa o próximo proxy em círculo
for i in range(9):
    proxies = get_next_proxy()
    response = requests.get("https://httpbin.org/ip", proxies=proxies, timeout=10)
    print(f"Solicitação {i+1}: {response.json()['origin']}")
  

Para tarefas industriais com milhares de solicitações por hora, recomenda-se usar proxies residenciais com rotação automática embutida — o provedor troca o IP para cada solicitação através de um único endpoint, e você não precisa gerenciar a lista de endereços manualmente.

Proxy através de Session: conexões persistentes e cookies

Quando você precisa fazer várias solicitações dentro de uma única sessão (por exemplo, fazer login e depois fazer solicitações), use o objeto requests.Session(). Ele mantém cookies, cabeçalhos e configurações de proxy entre as solicitações — não é necessário passar o proxy em cada chamada separadamente.

import requests

# Criando uma sessão com proxy
session = requests.Session()
session.proxies = {
    "http": "http://user:[email protected]:8080",
    "https": "http://user:[email protected]:8080",
}

# Adicionando cabeçalhos para simular um navegador
session.headers.update({
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
    "Accept-Language": "pt-BR,pt;q=0.9",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
})

# Passo 1: Autenticação
login_data = {"username": "myuser", "password": "mypass"}
session.post("https://example.com/login", data=login_data)

# Passo 2: Solicitações já com cookies e através do proxy
response = session.get("https://example.com/dashboard")
print(response.status_code)

# Passo 3: Fechando a sessão
session.close()
  

Usar Session também é mais eficiente em termos de desempenho: a conexão TCP é reutilizada, em vez de ser aberta novamente para cada solicitação. Ao fazer scraping de 1000+ páginas, isso proporciona um aumento significativo na velocidade.

Tratamento de erros, timeouts e tentativas automáticas

Servidores proxy podem estar indisponíveis, responder lentamente ou retornar erros de conexão. Um script confiável para scraping deve ser capaz de lidar com essas situações e alternar automaticamente para outro proxy em caso de falha.

import requests
import random
import time

proxy_list = [
    "http://user:[email protected]:8080",
    "http://user:[email protected]:8080",
    "http://user:[email protected]:8080",
]

def fetch_with_retry(url, max_retries=3, timeout=10):
    """
    Faz uma solicitação com troca automática de proxy em caso de erro.
    Retorna um objeto Response ou None se as tentativas se esgotarem.
    """
    available_proxies = proxy_list.copy()
    random.shuffle(available_proxies)

    for attempt, proxy_url in enumerate(available_proxies[:max_retries], 1):
        proxies = {"http": proxy_url, "https": proxy_url}
        try:
            response = requests.get(
                url,
                proxies=proxies,
                timeout=timeout,
                headers={"User-Agent": "Mozilla/5.0"}
            )
            response.raise_for_status()  # Lança uma exceção para 4xx/5xx
            print(f"✓ Sucesso na tentativa {attempt}")
            return response

        except requests.exceptions.ProxyError:
            print(f"✗ Tentativa {attempt}: proxy indisponível — {proxy_url}")
        except requests.exceptions.Timeout:
            print(f"✗ Tentativa {attempt}: timeout — {proxy_url}")
        except requests.exceptions.HTTPError as e:
            print(f"✗ Tentativa {attempt}: erro HTTP {e.response.status_code}")
            if e.response.status_code == 403:
                print("  → Banido, tentando o próximo proxy...")
        except requests.exceptions.RequestException as e:
            print(f"✗ Tentativa {attempt}: erro geral — {e}")

        time.sleep(1)  # Pausa entre as tentativas

    print(f"✗ Todas as {max_retries} tentativas se esgotaram para {url}")
    return None

# Uso
result = fetch_with_retry("https://httpbin.org/ip")
if result:
    print(result.json())
  

Note o raise_for_status() — esse método lança automaticamente uma exceção para status HTTP 4xx e 5xx. Sem ele, o script considerará bem-sucedida até mesmo uma resposta com código 403 (banimento) ou 429 (limite de solicitações excedido).

Proxy através de variáveis de ambiente: armazenamento seguro de dados

A biblioteca requests lê automaticamente as variáveis de ambiente HTTP_PROXY e HTTPS_PROXY. Isso permite que você não armazene credenciais no código e troque facilmente entre proxies sem alterar o script.

Definindo variáveis no terminal (Linux/macOS):

export HTTP_PROXY="http://user:[email protected]:8080"
export HTTPS_PROXY="http://user:[email protected]:8080"
export NO_PROXY="localhost,127.0.0.1"
  

Ou através de um arquivo .env com a biblioteca python-dotenv:

# Arquivo .env (adicione ao .gitignore!)
HTTP_PROXY=http://user:[email protected]:8080
HTTPS_PROXY=http://user:[email protected]:8080
  
# Script Python
from dotenv import load_dotenv
import requests
import os

load_dotenv()  # Carregando variáveis do .env

# requests usa automaticamente HTTP_PROXY e HTTPS_PROXY
response = requests.get("https://httpbin.org/ip")
print(response.json())

# Ou explicitamente das variáveis de ambiente:
proxies = {
    "http": os.getenv("HTTP_PROXY"),
    "https": os.getenv("HTTPS_PROXY"),
}
response = requests.get("https://httpbin.org/ip", proxies=proxies)
print(response.json())
  

⚠️ Importante: variável NO_PROXY

A variável NO_PROXY permite excluir certos endereços da proxy. Certifique-se de adicionar localhost e 127.0.0.1 para que as solicitações locais não passem pelo proxy.

Cenários reais: scraping de marketplaces, trabalho com API e automação

Vamos considerar três cenários práticos com os quais os desenvolvedores frequentemente se deparam.

Cenário 1: Scraping de preços de um marketplace

Ao monitorar preços no Wildberries ou Ozon, é importante simular o comportamento de um usuário real: passar os cabeçalhos corretos do navegador, adicionar atrasos entre as solicitações e rotacionar os IPs. Para essa tarefa, proxies de data center são uma boa escolha — eles são rápidos e baratos ao trabalhar com grandes volumes de dados.

import requests
import time
import random

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": "application/json, text/plain, */*",
    "Accept-Language": "pt-BR,pt;q=0.9",
    "Referer": "https://www.wildberries.ru/",
}

PROXIES = [
    {"http": "http://user:[email protected]:8080",
     "https": "http://user:[email protected]:8080"},
    {"http": "http://user:[email protected]:8080",
     "https": "http://user:[email protected]:8080"},
]

def get_product_price(article_id: int) -> dict:
    """Obtém o preço do produto pelo artigo no Wildberries."""
    url = f"https://card.wb.ru/cards/v1/detail?appType=1&curr=rub&nm={article_id}"
    proxies = random.choice(PROXIES)

    try:
        resp = requests.get(url, headers=HEADERS, proxies=proxies, timeout=15)
        resp.raise_for_status()
        data = resp.json()
        product = data["data"]["products"][0]
        return {
            "id": product["id"],
            "name": product["name"],
            "price": product["salePriceU"] / 100,  # preço em centavos
        }
    except (requests.RequestException, KeyError, IndexError) as e:
        return {"error": str(e)}

# Scraping de vários artigos com atraso
articles = [12345678, 87654321, 11223344]
for article in articles:
    result = get_product_price(article)
    print(result)
    time.sleep(random.uniform(1.5, 3.0))  # Atraso aleatório de 1.5-3 seg
  

Cenário 2: Trabalho com API através de proxy

Algumas APIs limitam o número de solicitações de um único IP (limitação de taxa). Distribuir solicitações entre vários proxies permite contornar essa limitação:

import requests
import itertools
from typing import Optional

class ProxyAPIClient:
    """Cliente para trabalhar com API através de rotação de proxies."""

    def __init__(self, api_key: str, proxy_list: list):
        self.api_key = api_key
        self.proxy_cycle = itertools.cycle(proxy_list)
        self.session = requests.Session()
        self.session.headers.update({
            "Authorization": f"Bearer {api_key}",
            "Content-Type": "application/json",
        })

    def _get_proxy(self) -> dict:
        proxy = next(self.proxy_cycle)
        return {"http": proxy, "https": proxy}

    def get(self, url: str, **kwargs) -> Optional[dict]:
        proxies = self._get_proxy()
        try:
            resp = self.session.get(url, proxies=proxies, timeout=10, **kwargs)
            resp.raise_for_status()
            return resp.json()
        except requests.RequestException as e:
            print(f"Solicitação API falhou: {e}")
            return None

# Uso
proxy_list = [
    "http://user:[email protected]:8080",
    "http://user:[email protected]:8080",
]

client = ProxyAPIClient(api_key="your_api_key", proxy_list=proxy_list)
data = client.get("https://api.example.com/products")
  

Cenário 3: Teste de geolocalização

Profissionais de marketing e SEO frequentemente verificam como um site aparece de diferentes regiões. Com proxies de locais desejados, é possível automatizar esse processo:

import requests

# Proxies de diferentes regiões
regional_proxies = {
    "Moscovo":        "http://user:[email protected]:8080",
    "São Petersburgo": "http://user:[email protected]:8080",
    "Novosibirsk":   "http://user:[email protected]:8080",
    "EUA":           "http://user:[email protected]:8080",
}

url = "https://example.com/prices"

for region, proxy_url in regional_proxies.items():
    proxies = {"http": proxy_url, "https": proxy_url}
    try:
        resp = requests.get(url, proxies=proxies, timeout=15)
        print(f"[{region}] Status: {resp.status_code} | "
              f"Tamanho: {len(resp.content)} bytes")
    except requests.RequestException as e:
        print(f"[{region}] Erro: {e}")
  

Qual tipo de proxy escolher para sua tarefa

A escolha do tipo de proxy afeta diretamente o sucesso do seu projeto. Um proxy de data center barato pode funcionar bem para algumas tarefas e falhar completamente para outras. Aqui está um guia prático para a escolha:

Tarefa Tipo de proxy Por que
Scraping de marketplaces (Wildberries, Ozon) Residenciais Parecem usuários comuns, são banidos com menos frequência
Scraping de dados abertos, notícias Data centers Rápidos, baratos, suficientemente anônimos
Trabalho com API do Facebook, Instagram Móveis Redes sociais confiam mais em IPs móveis
Teste de geolocalização Residenciais com geotargeting Geolocalização precisa, IPs reais da região desejada
Scraping de alta carga (10k+ solicitações/hora) Data centers (pool) Velocidade e custo em grandes volumes
Autenticação e trabalho com contas Residenciais ou móveis Menos gatilhos para sistemas antifraude

Para tarefas onde a máxima confiabilidade e o mínimo risco de bloqueio ao trabalhar com sites protegidos são importantes, os desenvolvedores frequentemente escolhem proxies móveis — eles usam endereços IP de operadoras móveis reais (MTS, Beeline, MegaFon), que raramente entram em listas de bloqueio.

Checklist para verificar proxies antes de usar

  • ✅ Verifique o IP através de httpbin.org/ip — seu endereço real está visível?
  • ✅ Verifique a velocidade — o tempo de resposta não deve exceder 2-3 segundos
  • ✅ Certifique-se de que o proxy não está em listas de bloqueio através de blocklist.de ou ipqualityscore.com
  • ✅ Verifique a geolocalização através de ipinfo.io — coincide com a região esperada?
  • ✅ Teste no site alvo com uma única solicitação antes de executar o script completo
  • ✅ Certifique-se de que o tráfego HTTPS também passa pelo proxy (ambas as chaves no dicionário)

Conclusão

Configurar proxies em Python requests não é difícil, mas requer atenção aos detalhes. Os principais princípios a serem lembrados: sempre especifique ambas as chaves (http e https) no dicionário de proxies, use Session para cenários de várias etapas, sempre trate erros e timeouts, e armazene credenciais em variáveis de ambiente, não no código.

Para scraping industrial com milhares de solicitações por dia, uma lista manual de proxies não é suficiente — é necessária rotação. Se você está fazendo scraping de marketplaces protegidos como Wildberries ou Ozon, trabalhando com redes sociais ou testando geolocalização, recomendamos experimentar proxies residenciais — eles oferecem um alto nível de confiança por parte dos sistemas anti-bot e suportam rotação automática de IP através de um único endpoint, o que simplifica significativamente o código do seu script.

```