Resposta rápida
Como funcionam sessões fixas e rotação de IP em um proxy residencial?
No CrawlRelay, um nome de usuário sem ID de sessão recebe um IP do pool a cada nova conexão TCP, geralmente diferente, e -session-<id>-ttl-<minutes> mantém um IP para aquele ID por até 30 minutos, embora o IP possa mudar antes. A rotação segue conexões, não requisições HTTP, então manter-vivo decide quando seu IP realmente muda. Tráfego residencial custa US$ 0,50/GB a partir de 50 GB. Paga-se com cripto, sem KYC.
Regras de sessão em resumo
| Unidade de rotação | Um IP do pool por nova conexão TCP, geralmente diferente |
|---|---|
| Sessão fixa | -session-<id>-ttl-<minutes> anexado ao nome de usuário |
| Duração da sessão | até 30 minutos |
| ID de sessão | 1–32 letras ou dígitos; um ID por fluxo |
| O que encerra uma sessão antes do tempo | O dispositivo residencial por trás dela desconectando |
| IDs compartilhados | Clientes que enviam o mesmo ID compartilham a mesma saída |
| Custo | Nenhum: sessões e rotação estão incluídas no preço por GB |
O que acontece no gateway quando envio um ID de sessão?
O gateway lê o nome de usuário em cada nova conexão. Sem uma parte de sessão, ele escolhe uma saída residencial que corresponde ao seu direcionamento apenas para aquela conexão. Com uma parte de sessão, mantém a mesma saída para esse ID pelo TTL que você definir.
Um IP fixo é uma conexão residencial real, então pode desaparecer antes do TTL acabar: o dispositivo pode ser desligado, perder o Wi-Fi ou mudar de rede. Fluxos longos devem suportar isso, verificando o IP de saída em pontos de controle e reiniciando a partir de um ponto de controle em vez de falhar o trabalho todo.
Como cada biblioteca reutiliza conexões?
Se uma biblioteca mantém a conexão viva, cada requisição nela compartilha uma saída. É assim que se obtém cada comportamento propositalmente.
| Biblioteca | Padrão | IP novo a cada requisição | Um IP para um fluxo |
|---|---|---|---|
| Python requests | Session mantém conexões vivas | Cabeçalho Connection: close, ou um novo Session por requisição | Um Session com um ID de sessão no nome de usuário |
| httpx | Cliente mantém conexões agrupadas | httpx.Limits(max_keepalive_connections=0) | Um cliente por ID de sessão |
| aiohttp | TCPConnector agrupa conexões | TCPConnector(force_close=True) | ID de sessão no nome de usuário da URL do proxy |
| Scrapy | Grupos por credenciais de proxy e host | meta={"proxy_session": "new"} com nosso middleware | Um proxy_session fixo para o fluxo |
| Playwright / Puppeteer | Chrome agrupa por contexto | Novo contexto por página | Um contexto por ID de sessão |
| Node.js undici, axios, got | Agentes mantêm sockets vivos | Novo agente por requisição, ou keep-alive desligado | Um agente por ID de sessão |
| curl | Uma conexão por comando | Já é o caso | Mesmo ID de sessão em cada comando |
Qual estratégia de sessão cabe em qual trabalho de scraping?
| Trabalho | Estratégia | TTL sugerido |
|---|---|---|
| Produtos independentes, artigos ou páginas de listagem | Rotacionar: sem ID de sessão | — |
| Paginação cuja próxima página depende de um cookie ou cursor | Uma sessão sticky por listagem | 10–30 min |
| Pesquisar, depois resultados, depois páginas de detalhe | Uma sessão sticky por busca | 10–20 min |
| Renderização com navegador headless de várias páginas de um site | Uma sessão sticky por contexto do navegador | A vida do contexto, até 30 min |
| Verificar o que uma página mostra em várias cidades | Uma sessão curta por verificação de cidade | 5 min |
| Rever a mesma página a cada hora | Rotacionar | — |
Como gerencio um pool de sessões sticky em Python?
Um pequeno pool distribui a carga por algumas saídas estáveis e aposenta cada uma após determinado número de requisições ou ao sinal de que a saída está falhando, como 502 ou 503. Note o que ele não faz: não troca IPs para passar por um 403 ou 429. Isso significa que o site quer que você desacelere, então o pool levanta esses erros para seu código.
import random
import uuid
import requests
GATEWAY = "gw.crawlrelay.com:7777"
BASE_USER, PASSWORD = "USERNAME-country-us", "PASSWORD"
class SlowDown(Exception):
"""The target asked us to slow down (403 or 429): back off, do not rotate."""
class StickySession:
def __init__(self, ttl=15, max_requests=50):
self.id = uuid.uuid4().hex[:10]
self.max_requests, self.used = max_requests, 0
user = "%s-session-%s-ttl-%d" % (BASE_USER, self.id, ttl)
proxy = "http://%s:%s@%s" % (user, PASSWORD, GATEWAY)
self.http = requests.Session()
self.http.proxies = {"http": proxy, "https": proxy}
class SessionPool:
EXIT_PROBLEMS = {502, 503, 504}
def __init__(self, size=5, **options):
self.options = options
self.sessions = [StickySession(**options) for _ in range(size)]
def _replace(self, i):
self.sessions[i].http.close()
self.sessions[i] = StickySession(**self.options)
def get(self, url, **kwargs):
i = random.randrange(len(self.sessions))
s = self.sessions[i]
s.used += 1
try:
r = s.http.get(url, timeout=(10, 30), **kwargs)
except requests.exceptions.RequestException:
self._replace(i) # dropped exit or timeout: start a fresh session
raise
if r.status_code in (403, 429):
raise SlowDown("%s returned %d" % (url, r.status_code))
if r.status_code in self.EXIT_PROBLEMS or s.used >= s.max_requests:
self._replace(i)
return r
pool = SessionPool(size=5, ttl=15, max_requests=50)
print(pool.get("https://api.ipify.org").text)Como sei que um IP sticky mudou?
Pergunte. Solicite um serviço de eco de IP como https://api.ipify.org na mesma sessão no início do fluxo e em cada checkpoint, e compare as respostas. Uma mudança indica que a saída atrás da sessão mudou: reinicie o fluxo do último checkpoint ou abra uma nova sessão. Registre isso com o ID da sessão para diferenciar mudanças de IP do comportamento do site na depuração.
Quais erros de sessão custam mais?
- Rotacionar a cada requisição de um fluxo multi-etapas. O site vê um carrinho, cursor ou token de busca pulando entre países e reinicia.
- Um ID de sessão para cada worker. Uma sessão é para um fluxo; dê a cada worker e fluxo o seu próprio ID.
- Sessões muito mais longas que o trabalho. TTL de 30 minutos para fluxo de 2 minutos ocupa IP sem necessidade e dificulta a leitura dos logs.
- Tratar um 429 como problema de IP. Novo IP não altera regra do site; desacelerar sim. Veja 429 Too Many Requests.
- Assumir rotação por requisição. Keep-alive mantém a saída; confira a tabela acima para sua biblioteca.
Sessões e rotação: perguntas
Quanto tempo dura uma sessão sticky?
Sessões sticky mantêm o mesmo IP pelo tempo que você escolher (ttl, em minutos), até 30 minutos. O IP pode mudar antes, por exemplo se o dispositivo residencial desconectar. Escolha um TTL um pouco maior que o fluxo que atende e cheque a saída nos checkpoints.
Uma sessão sticky custa mais que a rotação?
Não. CrawlRelay cobra tráfego por GB, e sessões, rotação e segmentação estão incluídas. Uma sessão sticky pode até economizar tráfego, pois uma conexão keep-alive evita novo handshake TLS a cada requisição.
Rotacionar a cada requisição é melhor para scraping?
Para páginas independentes, rotacionar distribui carga e evita acessar um site de um único IP por horas. Para qualquer coisa com estado, como paginação atrelada a cookie, quebra o fluxo. A maioria dos crawls mistura ambos: rotaciona entre itens, mantém sticky dentro do fluxo.
Posso escolher o IP exato que recebo?
Não. Um gateway residencial atribui saídas de um pool que muda o tempo todo, conforme a segmentação no seu usuário. Você escolhe país, cidade, estado dos EUA, CEP ou ASN, e pode manter o IP com sessão; não pode reservar endereço específico.
Rotação e sessões estão em todos os planos
US$ 1,50 por 1 GB, US$ 0,50/GB a partir de 50 GB.