Como corrigir problemas com cookies através de proxy
Os cookies são uma das fontes mais frequentes de erros ao trabalhar com proxy. As sessões são interrompidas, a autorização falha, os dados são perdidos. Neste artigo, entenderemos por que isso acontece e como configurar corretamente o tratamento de cookies para um funcionamento estável.
Por que os cookies são perdidos ao usar proxy
Quando você envia uma requisição através de um proxy, um nó intermediário fica entre seu cliente e o servidor de destino. Isso cria vários problemas:
- Endereços IP diferentes para uma sessão. O servidor pode notar que as requisições vêm de endereços diferentes e rejeitar os cookies como suspeitos.
- Perda de cabeçalhos Set-Cookie. Uma configuração incorreta do proxy pode não transmitir os cabeçalhos Set-Cookie ao cliente.
- Incompatibilidade de domínio e caminho. Se o proxy reescreve o cabeçalho Host, os cookies podem não ser salvos devido à incompatibilidade de domínio.
- Falta de preservação de estado. Se você enviar cada requisição separadamente sem salvar cookies, a sessão será perdida.
O que é cookie jar e como usá-lo
Cookie jar é um armazenamento de cookies que gerencia automaticamente seu envio e recebimento. Em vez de adicionar manualmente cabeçalhos Cookie em cada requisição, você permite que a biblioteca faça isso automaticamente.
A maioria dos clientes HTTP tem suporte integrado para cookie jar:
import requests
from requests.cookies import RequestsCookieJar
# Criamos um jar para armazenar cookies
jar = RequestsCookieJar()
# Primeira requisição — o servidor enviará Set-Cookie
response1 = requests.get(
'https://example.com/login',
cookies=jar,
proxies={'https': 'http://proxy.example.com:8080'}
)
# Os cookies são salvos automaticamente no jar
print(jar)
# Segunda requisição — os cookies serão enviados automaticamente
response2 = requests.get(
'https://example.com/dashboard',
cookies=jar,
proxies={'https': 'http://proxy.example.com:8080'}
)
Sem jar, você teria que analisar manualmente Set-Cookie e adicioná-los à próxima requisição — isso é pouco confiável e complicado.
Salvando cookies entre requisições
Se seu script funciona por muito tempo ou você precisa restaurar a sessão após uma reinicialização, salve os cookies em um arquivo:
import requests
from http.cookiejar import LWPCookieJar
# Criamos um jar com salvamento em arquivo
jar = LWPCookieJar('cookies.txt')
# Carregamos cookies antigos se existirem
try:
jar.load(ignore_discard=True, ignore_expires=True)
except FileNotFoundError:
pass
# Usamos jar nas requisições
response = requests.get(
'https://example.com/login',
cookies=jar,
proxies={'https': 'http://proxy.example.com:8080'}
)
# Salvamos cookies atualizados
jar.save(ignore_discard=True, ignore_expires=True)
Os sinalizadores ignore_discard=True e ignore_expires=True permitem salvar até cookies temporários.
Problemas com vinculação de domínio de cookies
Os cookies têm um atributo Domain que determina para quais domínios eles serão enviados. Os problemas surgem se:
- O proxy reescreve o Host. Se o proxy alterar o cabeçalho Host, o cookie jar pode rejeitar o cookie como pertencente a outro domínio.
- Os subdomínios não correspondem. Um cookie para
example.compode não ser enviado paraapi.example.com. - O caminho não corresponde. Um cookie para
/apinão será enviado para/admin.
Verifique os atributos do cookie assim:
import requests
response = requests.get(
'https://example.com',
proxies={'https': 'http://proxy.example.com:8080'}
)
# Exibimos todos os cookies
for cookie in response.cookies:
print(f"Name: {cookie.name}")
print(f"Value: {cookie.value}")
print(f"Domain: {cookie.domain}")
print(f"Path: {cookie.path}")
print(f"Secure: {cookie.secure}")
print(f"HttpOnly: {cookie.has_nonstandard_attr('HttpOnly')}")
print("---")
Se o Domain for muito restritivo, tente especificar explicitamente os cookies em vez de gerenciamento automático:
headers = {
'Cookie': 'session_id=abc123; user_token=xyz789'
}
response = requests.get(
'https://example.com/api',
headers=headers,
proxies={'https': 'http://proxy.example.com:8080'}
)
Sinalizadores Secure e HttpOnly
O sinalizador Secure significa que o cookie é enviado apenas por HTTPS. Se você usar um proxy HTTP para acessar um recurso HTTPS, certifique-se de que a conexão com o proxy está protegida ou que o proxy encaminha corretamente o HTTPS.
O sinalizador HttpOnly proíbe o acesso ao cookie a partir do JavaScript. Isso não afeta o envio do cookie nas requisições, mas é importante lembrar que você não poderá ler esses cookies do navegador.
Ao trabalhar com proxies residenciais, certifique-se de que:
- O proxy suporta HTTPS (método CONNECT)
- Os certificados são válidos (não use
verify=Falseem produção) - Os cabeçalhos não são reescritos pelo proxy
Exemplos práticos com código
Exemplo 1: Login com preservação de sessão
import requests
from requests.cookies import RequestsCookieJar
jar = RequestsCookieJar()
proxy = 'http://proxy.example.com:8080'
# Login
login_response = requests.post(
'https://example.com/login',
data={'username': 'user', 'password': 'pass'},
cookies=jar,
proxies={'https': proxy}
)
if login_response.status_code == 200:
print("Login bem-sucedido")
# Usamos a sessão salva
dashboard = requests.get(
'https://example.com/dashboard',
cookies=jar,
proxies={'https': proxy}
)
print(dashboard.text)
Exemplo 2: Processamento de múltiplas requisições
import requests
from http.cookiejar import LWPCookieJar
import time
jar = LWPCookieJar('session.txt')
try:
jar.load(ignore_discard=True)
except:
pass
proxy = 'http://proxy.example.com:8080'
urls = [
'https://example.com/page1',
'https://example.com/page2',
'https://example.com/page3'
]
for url in urls:
response = requests.get(
url,
cookies=jar,
proxies={'https': proxy},
timeout=10
)
print(f"{url}: {response.status_code}")
jar.save(ignore_discard=True)
time.sleep(1) # Não sobrecarregue o servidor
Exemplo 3: Transmissão explícita de cookies em caso de problemas
import requests
proxy = 'http://proxy.example.com:8080'
# Se o gerenciamento automático não funcionar
cookies_dict = {
'session_id': 'abc123def456',
'user_pref': 'dark_mode'
}
headers = {
'User-Agent': 'Mozilla/5.0...',
'Cookie': '; '.join([f"{k}={v}" for k, v in cookies_dict.items()])
}
response = requests.get(
'https://example.com/api/data',
headers=headers,
proxies={'https': proxy}
)
print(response.json())
Depuração de problemas com cookies
Se os cookies não funcionarem, use estas ferramentas:
| Ferramenta | Finalidade |
|---|---|
requests.Session |
Gerencia automaticamente cookies para todas as requisições na sessão |
logging |
Ative DEBUG para requests para ver todos os cabeçalhos |
Fiddler / Charles |
Intercepte o tráfego e veja os cabeçalhos Set-Cookie e Cookie |
curl -v |
Teste o mesmo através do proxy a partir da linha de comando |
Ative o registro para depuração:
import logging
import requests
logging.basicConfig(level=logging.DEBUG)
# Agora todas as requisições exibirão cabeçalhos e cookies
response = requests.get(
'https://example.com',
proxies={'https': 'http://proxy.example.com:8080'}
)
Verifique se o proxy não está bloqueando cookies:
curl -v -x http://proxy.example.com:8080 https://example.com
# Procure pelos cabeçalhos:
# Set-Cookie: ... (devem estar presentes)
# Cookie: ... (devem ser enviados na próxima requisição)
Dica: Se você usar proxies residenciais, lembre-se de que eles podem rotacionar o IP entre requisições. Certifique-se de que sua lógica de tratamento de cookies leva isso em conta — alguns servidores rejeitam requisições com IPs diferentes na mesma sessão.
Resumo
Os problemas com cookies ao trabalhar através de proxy são resolvidos com a configuração correta:
- Use cookie jar para gerenciamento automático de cookies
- Salve cookies entre requisições em um arquivo
- Verifique a vinculação de domínio e atributos de Path
- Certifique-se do suporte a HTTPS do proxy
- Use depuração para identificar problemas
Para tarefas de automação e scraping, onde é necessário um funcionamento confiável com sessões através de proxy, proxies residenciais com suporte a HTTPS e gerenciamento de cookies são adequados. Comece com um cookie jar simples e mude para esquemas mais complexos apenas se necessário.