Voltar ao blog

Por Que o Proxy Funciona no Navegador, Mas Não no Código: Análise Completa do Problema

Proxy funciona bem no navegador, mas o script retorna erros? Analisamos as causas comuns e fornecemos soluções prontas para Python, Node.js e cURL.

📅11 de dezembro de 2025
```html

Por que o proxy funciona no navegador, mas não no código: uma análise completa do problema

Situação clássica: você configura um proxy no navegador, abre um site — tudo funciona. Você executa um script com o mesmo proxy — erro de conexão, timeout ou banimento. Vamos entender por que isso acontece e como corrigir.

Como uma requisição do navegador difere de uma requisição de código

Quando você abre um site no navegador através de um proxy, acontece muito mais do que apenas uma requisição HTTP. O navegador faz automaticamente o seguinte:

  • Envia um conjunto completo de cabeçalhos (User-Agent, Accept, Accept-Language, Accept-Encoding)
  • Executa o TLS-handshake com um conjunto de cifras correto
  • Gerencia redirecionamentos e cookies
  • Executa JavaScript e carrega recursos dependentes
  • Armazena em cache respostas DNS e certificados

Uma requisição mínima de código parece completamente diferente para o servidor — como um robô, e não como um humano. Mesmo que o proxy funcione corretamente, o site de destino pode estar bloqueando especificamente seu script.

Problemas com a autenticação do proxy

A causa mais comum é a transmissão incorreta de login e senha. O navegador exibe uma janela pop-up para inserir as credenciais, mas no código, isso precisa ser feito explicitamente.

Formato de URL incorreto

Um erro comum é omitir o esquema ou codificar incorretamente caracteres especiais:

# Incorreto
proxy = "user:pass@proxy.example.com:8080"

# Correto
proxy = "http://user:pass@proxy.example.com:8080"

# Se a senha contiver caracteres especiais (@, :, /)
from urllib.parse import quote
password = quote("p@ss:word/123", safe="")
proxy = f"http://user:{password}@proxy.example.com:8080"

Autenticação por IP vs. login/senha

Alguns provedores de proxy usam uma lista de permissões (whitelist) baseada em endereço IP. O navegador no seu computador funciona porque seu IP está na whitelist. Mas o script em um servidor não funciona, porque o servidor tem um IP diferente.

Verifique no painel do provedor qual método de autenticação está sendo usado e quais IPs estão na whitelist.

Incompatibilidade de protocolos HTTP/HTTPS/SOCKS

O navegador geralmente detecta o tipo de proxy automaticamente. No código, você precisa especificar explicitamente, e um erro no protocolo leva a uma falha silenciosa.

Tipo de Proxy Esquema no URL Características
Proxy HTTP http:// Funciona para HTTP e HTTPS via CONNECT
Proxy HTTPS https:// Conexão criptografada com o proxy
SOCKS4 socks4:// Sem autenticação, apenas IPv4
SOCKS5 socks5:// Com autenticação, UDP, IPv6
SOCKS5h socks5h:// Resolução DNS através do proxy

É crucial: se você tem um proxy SOCKS5, mas especifica http://, a conexão não será estabelecida. A biblioteca tentará se comunicar via protocolo HTTP com um servidor SOCKS.

Ausência de cabeçalhos e impressão digital (fingerprint)

Mesmo que o proxy funcione corretamente, o site de destino pode bloquear a requisição devido a cabeçalhos suspeitos. Compare:

Requisição do navegador

GET /api/data HTTP/1.1
Host: example.com
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,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1

Requisição padrão com requests

GET /api/data HTTP/1.1
Host: example.com
User-Agent: python-requests/2.28.0
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive

A diferença é óbvia. Um site com proteção anti-bot identificará instantaneamente que a requisição não veio de um navegador.

Conjunto mínimo de cabeçalhos para mascaramento

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",
    "Connection": "keep-alive",
    "Upgrade-Insecure-Requests": "1",
    "Sec-Fetch-Dest": "document",
    "Sec-Fetch-Mode": "navigate",
    "Sec-Fetch-Site": "none",
    "Sec-Fetch-User": "?1",
    "Cache-Control": "max-age=0"
}

Certificados SSL e verificação

O navegador possui um armazenamento interno de certificados raiz e sabe lidar com várias configurações SSL. No código, podem surgir problemas:

Erro SSL: CERTIFICATE_VERIFY_FAILED

Alguns proxies usam seus próprios certificados para inspeção de tráfego. O navegador pode ter este certificado como confiável, mas seu script não.

# Solução temporária para depuração (NÃO para produção!)
import requests
response = requests.get(url, proxies=proxies, verify=False)

# Solução correta — especificar o caminho para o certificado
response = requests.get(url, proxies=proxies, verify="/path/to/proxy-ca.crt")

Importante: Desativar a verificação SSL (verify=False) torna a conexão vulnerável a ataques MITM. Use apenas para depuração em um ambiente seguro.

TLS Fingerprint

Sistemas anti-bot avançados analisam a impressão digital TLS — a ordem e o conjunto de cifras ao estabelecer a conexão. O Python requests usa um conjunto padrão que difere do navegador.

Para contornar isso, use bibliotecas com impressão digital TLS personalizada:

# Instalação: pip install curl-cffi
from curl_cffi import requests

response = requests.get(
    url,
    proxies={"https": proxy},
    impersonate="chrome120"  # Imita a impressão digital TLS do Chrome 120
)

Vazamentos de DNS e resolução

Outro problema não óbvio é a resolução DNS. Ao usar um proxy HTTP, a requisição DNS pode ir diretamente da sua máquina, ignorando o proxy.

Como isso afeta o funcionamento

  • O site vê o resolvedor DNS real, e não o proxy
  • A geolocalização é determinada incorretamente
  • Alguns sites bloqueiam a incompatibilidade entre o IP e a região do DNS

Solução para SOCKS5

Use o esquema socks5h:// em vez de socks5:// — a letra "h" significa que a resolução DNS será executada no lado do proxy:

# DNS é resolvido localmente (vazamento!)
proxy = "socks5://user:pass@proxy.example.com:1080"

# DNS é resolvido via proxy (correto)
proxy = "socks5h://user:pass@proxy.example.com:1080"

Exemplos funcionais para Python, Node.js e cURL

Python com requests

import requests
from urllib.parse import quote

# Dados do proxy
proxy_host = "proxy.example.com"
proxy_port = "8080"
proxy_user = "username"
proxy_pass = quote("p@ssword!", safe="")  # Codifica caracteres especiais

# Forma a URL do proxy
proxy_url = f"http://{proxy_user}:{proxy_pass}@{proxy_host}:{proxy_port}"

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

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,*/*;q=0.8",
    "Accept-Language": "en-US,en;q=0.9",
    "Accept-Encoding": "gzip, deflate, br",
}

try:
    response = requests.get(
        "https://httpbin.org/ip",
        proxies=proxies,
        headers=headers,
        timeout=30
    )
    print(f"Status: {response.status_code}")
    print(f"IP: {response.json()}")
except requests.exceptions.ProxyError as e:
    print(f"Erro de proxy: {e}")
except requests.exceptions.ConnectTimeout:
    print("Tempo limite de conexão com o proxy")

Python com aiohttp (assíncrono)

import aiohttp
import asyncio

async def fetch_with_proxy():
    proxy_url = "http://user:pass@proxy.example.com:8080"
    
    async with aiohttp.ClientSession() as session:
        async with session.get(
            "https://httpbin.org/ip",
            proxy=proxy_url,
            headers={"User-Agent": "Mozilla/5.0..."}
        ) as response:
            return await response.json()

result = asyncio.run(fetch_with_proxy())
print(result)

Node.js com axios

const axios = require('axios');
const HttpsProxyAgent = require('https-proxy-agent');

const proxyUrl = 'http://user:pass@proxy.example.com:8080';
const agent = new HttpsProxyAgent(proxyUrl);

axios.get('https://httpbin.org/ip', {
    httpsAgent: agent,
    headers: {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36...'
    }
})
.then(response => console.log(response.data))
.catch(error => console.error('Error:', error.message));

Node.js com node-fetch e SOCKS

const fetch = require('node-fetch');
const { SocksProxyAgent } = require('socks-proxy-agent');

const agent = new SocksProxyAgent('socks5://user:pass@proxy.example.com:1080');

fetch('https://httpbin.org/ip', { agent })
    .then(res => res.json())
    .then(data => console.log(data));

cURL

# Proxy HTTP
curl -x "http://user:pass@proxy.example.com:8080" \
     -H "User-Agent: Mozilla/5.0..." \
     https://httpbin.org/ip

# Proxy SOCKS5 com DNS via proxy
curl --socks5-hostname "proxy.example.com:1080" \
     --proxy-user "user:pass" \
     https://httpbin.org/ip

# Depuração — mostrar todo o processo de conexão
curl -v -x "http://user:pass@proxy.example.com:8080" \
     https://httpbin.org/ip

Lista de verificação de diagnóstico

Se o proxy não funcionar no código, verifique em ordem:

  1. Formato do URL do proxy — o esquema (http://, socks5://) está presente?
  2. Caracteres especiais na senha — eles estão codificados via URL-encoding?
  3. Tipo de proxy — o protocolo especificado corresponde ao real?
  4. Autenticação — é por IP ou por login/senha? O IP do servidor está na whitelist?
  5. Cabeçalhos — o User-Agent e outros cabeçalhos de navegador foram adicionados?
  6. SSL — há erros de certificado?
  7. DNS — o socks5h:// está sendo usado para resolução via proxy?
  8. Timeouts — há tempo suficiente para a conexão (especialmente para proxies residenciais)?

Conclusão

A diferença entre o navegador e o código está nos detalhes: cabeçalhos, protocolos, SSL, DNS. O navegador esconde essa complexidade, mas no código, cada aspecto precisa ser configurado explicitamente. Comece verificando o formato do URL e a autenticação, depois adicione os cabeçalhos do navegador — isso resolve 90% dos problemas.

Para tarefas de raspagem (scraping) e automação onde a estabilidade e a baixa taxa de bloqueio são cruciais, os proxies residenciais são bem adequados — você pode saber mais sobre eles em proxycove.com.

```