Retry e rate limiting: como estruturar chamadas via proxy sem tomar bloqueio
Um erro comum ao integrar proxy: assumir que trocar de IP resolve qualquer bloqueio, então implementar retry agressivo sem se preocupar com taxa. Isso não só não resolve — em muitos casos, acelera o bloqueio, porque o padrão de retry em si é um sinal de automação.
Backoff exponencial, não retry linear
Retry imediato após falha (sem espera, ou espera fixa curta) cria um padrão de requisição fácil de identificar: muitas tentativas em sequência apertada. Backoff exponencial (espera crescente entre tentativas: 1s, 2s, 4s, 8s...) imita melhor o comportamento de um cliente real que encontra erro e tenta de novo depois de um tempo.
import time
def fetch_com_retry(url, max_tentativas=5):
for tentativa in range(max_tentativas):
try:
resposta = requests.get(url, proxies=proxies, timeout=10)
if resposta.status_code == 200:
return resposta
except requests.RequestException:
pass
time.sleep(2 ** tentativa)
raise Exception("Falhou após todas as tentativas")
Rate limiting no seu lado, não só no do destino
Muita gente só reage ao rate limit que o servidor impõe (erro 429). O ideal é impor seu próprio limite de taxa antes de bater no limite alheio — um scraper que já sabe que não deve passar de N requisições por minuto nunca aciona a defesa do outro lado.
Quando rotacionar IP vs quando só esperar
Nem todo 429/403 pede IP novo. Se o servidor está sinalizando limite de taxa (429 com header Retry-After), a resposta certa é esperar, não trocar de IP — trocar de IP mantendo o mesmo ritmo de requisição só desloca o problema. Reserve a rotação para quando o IP específico foi de fato bloqueado (403 persistente, não 429 temporário).
Próximos passos
Antes de aumentar o número de IPs disponíveis, revise sua lógica de retry — muitas vezes o gargalo real é o padrão de requisição, não a quantidade de endereços.
