Integrar proxies ao Scrapy-Splash permite que as requisições originadas do serviço de renderização Splash sejam roteadas por um servidor intermediário, viabilizando rotação de IP, desbloqueio geográfico e anonimato para páginas web renderizadas por JavaScript.
Entendendo a integração de proxy com o Scrapy-Splash
O Scrapy-Splash combina o framework de scraping do Scrapy com a capacidade de renderização em navegador headless do Splash. Quando um proxy é configurado nesse arranjo, significa que as requisições web feitas pela instância do navegador dentro do Splash são direcionadas ao servidor proxy especificado. Isso vale para o carregamento inicial da página, para as requisições AJAX subsequentes e para qualquer outra atividade de rede iniciada pelo JavaScript da página.
Por que usar proxies com o Scrapy-Splash?
Os proxies cumprem várias funções críticas ao fazer scraping de conteúdo dinâmico com o Scrapy-Splash:
* Contornar limites de taxa e bloqueios por IP: sites costumam restringir o acesso com base no endereço IP de origem. Proxies permitem distribuir as requisições entre vários IPs, mitigando essas restrições.
* Acessar conteúdo com restrição geográfica: proxies localizados em regiões geográficas específicas conseguem acessar conteúdo indisponível na localização física do scraper.
* Manter o anonimato: proxies ocultam o IP real do scraper, aumentando a segurança operacional.
* Distribuir a carga: em operações de grande escala, os proxies ajudam a distribuir a carga de rede e reduzem a chance de um único IP ser sobrecarregado ou sinalizado.
Como o Scrapy-Splash trata as requisições via proxy
- O Scrapy envia um
SplashRequestao daemon do Splash. - O Splash recebe a requisição e, se o argumento
proxyestiver presente, configura sua instância interna de navegador (por exemplo, Chromium) para rotear todo o tráfego de rede por esse proxy. - A instância do navegador navega até a URL alvo, renderiza o JavaScript e faz as chamadas de rede necessárias (por exemplo, XHRs, download de assets) via proxy configurado.
- O Splash devolve ao Scrapy o HTML totalmente renderizado, o screenshot ou outros dados solicitados.
Configurando proxies no Scrapy-Splash
O método principal de integração de proxy é o argumento proxy do SplashRequest.
Configuração básica de proxy
Para usar um proxy em uma requisição específica, passe o argumento proxy dentro do dicionário args do SplashRequest. O formato da URL do proxy é [protocol://][user:password@]host:port.
import scrapy
from scrapy_splash import SplashRequest
class BasicProxySpider(scrapy.Spider):
name = 'basic_proxy_spider'
start_urls = ['http://quotes.toscrape.com/js/']
def start_requests(self):
# Exemplo usando um proxy HTTP básico
# Substitua pelo IP e pela porta reais do seu proxy
yield SplashRequest(
url=self.start_urls[0],
callback=self.parse,
args={
'wait': 0.5,
'proxy': 'http://your_proxy_ip:port'
}
)
def parse(self, response):
title = response.css('title::text').get()
yield {
'title': title,
'url': response.url,
'proxy_used': response.request.meta.get('splash', {}).get('args', {}).get('proxy')
}
Proxies autenticados
Para proxies que exigem autenticação, embuta o usuário e a senha diretamente na string da URL do proxy.
import scrapy
from scrapy_splash import SplashRequest
class AuthenticatedProxySpider(scrapy.Spider):
name = 'auth_proxy_spider'
start_urls = ['http://quotes.toscrape.com/js/']
def start_requests(self):
# Substitua pelos dados reais do seu proxy
proxy_user = 'your_username'
proxy_pass = 'your_password'
proxy_host = 'your_proxy_ip'
proxy_port = 'port'
authenticated_proxy_url = f'http://{proxy_user}:{proxy_pass}@{proxy_host}:{proxy_port}'
yield SplashRequest(
url=self.start_urls[0],
callback=self.parse,
args={
'wait': 0.5,
'proxy': authenticated_proxy_url
}
)
def parse(self, response):
title = response.css('title::text').get()
yield {
'title': title,
'url': response.url,
'proxy_used': response.request.meta.get('splash', {}).get('args', {}).get('proxy')
}
Seleção dinâmica e rotação de proxies
Em cenários que exigem proxies diferentes por requisição ou um esquema de rotação, mantenha uma lista de proxies dentro do spider e selecione um dinamicamente.
import scrapy
from scrapy_splash import SplashRequest
import random
class RotatingProxySpider(scrapy.Spider):
name = 'rotating_proxy_spider'
start_urls = ['http://quotes.toscrape.com/js/', 'http://toscrape.com/']
# Defina uma lista de proxies (substitua pelos seus proxies reais)
# Inclua proxies autenticados como 'http://user:pass@host:port'
proxy_list = [
'http://proxy1_ip:port1',
'http://user:pass@proxy2_ip:port2',
'http://proxy3_ip:port3',
]
def start_requests(self):
for url in self.start_urls:
selected_proxy = random.choice(self.proxy_list)
yield SplashRequest(
url=url,
callback=self.parse,
args={
'wait': 0.5,
'proxy': selected_proxy
},
# Você também pode passar um meta personalizado para rastrear qual proxy foi usado
meta={'proxy_selected': selected_proxy}
)
def parse(self, response):
title = response.css('title::text').get()
yield {
'title': title,
'url': response.url,
'proxy_used': response.request.meta.get('proxy_selected') # Acessa o meta personalizado
}
Configuração global de proxy (daemon do Splash)
O Splash pode ser configurado para usar um proxy padrão em todas as suas requisições de saída. Isso normalmente é feito definindo as variáveis de ambiente HTTP_PROXY e HTTPS_PROXY antes de iniciar o daemon do Splash. Embora ofereça um padrão global, isso dá menos controle do que a especificação de proxy por requisição em tarefas de scraping dinâmicas.
Tipos de proxy e seu impacto
A escolha do tipo de proxy afeta anonimato, desempenho e risco de detecção.
| Aspecto | Proxies de datacenter | Proxies residenciais |
|---|---|---|
| Origem do IP | Data centers comerciais | ISPs residenciais reais |
| Anonimato | Moderado (IPs costumam pertencer a sub-redes conhecidas) | Alto (IPs aparecem como usuários comuns de internet) |
| Velocidade | Em geral mais rápidos, por causa da infraestrutura dedicada | Podem ser mais lentos por passarem por redes residenciais |
| Custo | Menor por IP | Maior por IP ou por banda |
| Detecção | Mais sujeitos a detecção e bloqueio por antibots sofisticados | Menos sujeitos a detecção; mais difíceis de bloquear |
| Casos de uso | Scraping geral, tarefas de alto volume em sites menos protegidos | Scraping muito sensível, contornar sistemas antibot avançados |
Protocolos de proxy
- Proxies HTTP/HTTPS: lidam com tráfego web padrão. O Splash suporta plenamente os dois protocolos.
- Proxies SOCKS: proxies SOCKS (SOCKS4, SOCKS5) operam em um nível mais baixo e conseguem lidar com diversos protocolos de rede, não apenas HTTP/HTTPS. Para usar um proxy SOCKS com o Splash, especifique o protocolo na URL do
proxy(por exemplo,socks5://user:pass@host:port).
Proxies sticky vs. rotativos
- Proxies sticky: mantêm o mesmo endereço IP por um período definido (por exemplo, de alguns minutos a horas) ou durante toda a sessão. Úteis para manter o estado de sessão em sites-alvo que exigem endereços IP consistentes.
- Proxies rotativos: atribuem um novo endereço IP a cada requisição ou em intervalos curtos e regulares. Ideais para scraping de alto volume, onde evitar banimentos de IP mudando frequentemente o IP de origem é crítico.
Solução de problemas e boas práticas
Verifique a conectividade do proxy
Antes de um deploy em larga escala, teste seu proxy de forma independente. Um simples comando curl ou um script Python com requests confirma a funcionalidade e a acessibilidade do proxy.
curl --proxy http://your_proxy_ip:port http://httpbin.org/ip
Confira os logs do Splash
Problemas de conectividade ou autenticação de proxy dentro do Splash costumam ser registrados pelo daemon do Splash. Revise a saída do console ou os arquivos de log do Splash ao depurar erros.
Trate erros de proxy com elegância
Implemente mecanismos de retry ou lógica de rotação de proxy para lidar com requisições falhas. Se um proxy falhar de forma consistente, remova-o do pool ativo ou marque-o como não saudável por um período. O middleware de retry do Scrapy pode ser adaptado, mas o tratamento de falhas específico de proxy geralmente exige lógica própria no spider.
Considerações de desempenho
Proxies acrescentam um salto de rede adicional, aumentando a latência.
* Gestão do pool de proxies: implemente um sistema para acompanhar a saúde dos proxies, os tempos de resposta e o uso. Priorize proxies mais rápidos e confiáveis.
* Uso de recursos: o próprio Splash é intensivo em recursos. Usar proxies adiciona overhead. Garanta que o daemon do Splash tenha CPU e RAM suficientes para a carga combinada.
Medidas antibot específicas do site
Sistemas antibot avançados detectam padrões que vão além do simples endereço IP. Mesmo com proxies residenciais, sites podem identificar navegação automatizada. Ajuste argumentos do Splash como user-agent, viewport, browser_params e use scripts Lua personalizados para interações mais humanas, contornando essas medidas.
Vazamento de IP
Confirme que o proxy realmente mascara o IP real do scraper. Use serviços como http://httpbin.org/ip ou https://ipleak.net/ dentro do Splash para verificar o IP visível.
# Script Lua para verificar o IP visível dentro do Splash
lua_script = """
function main(splash)
splash:set_proxy_auto() -- Garante que o proxy seja usado se definido pelo argumento 'proxy'
splash:go("http://httpbin.org/ip")
splash:wait(0.5)
return splash:html()
end
"""
# Exemplo de SplashRequest usando o script Lua
yield SplashRequest(
url="about:blank", # A URL aqui não importa, pois o Lua cuida da navegação
callback=self.parse_ip_check,
endpoint='execute',
args={
'lua_source': lua_script,
'proxy': 'http://your_proxy_ip:port',
'timeout': 90 # Aumente o timeout para scripts Lua
}
)
def parse_ip_check(self, response):
# Faz o parse do HTML de httpbin.org/ip para extrair o IP
ip_address = response.css('pre::text').get() # Ajuste o seletor se o httpbin mudar
self.logger.info(f"Visible IP from Splash via proxy: {ip_address}")
# Processamento adicional...
