Resposta rápida
Como usar um proxy com usuário e senha no Selenium?
Rode um pequeno forwarder local que adiciona o header Proxy-Authorization, e aponte o Chrome para ele com --proxy-server=http://127.0.0.1:8899. O Chrome ignora credenciais nesse flag, e o Selenium não tem opção portátil para senha de proxy. CrawlRelay proxies residenciais funcionam assim em gw.crawlrelay.com:7777, a partir de US$ 0,50/GB. Pago com cripto, sem KYC.
Setup do Selenium em resumo
| Por que um forwarder | A flag --proxy-server do Chrome não aceita usuário nem senha |
|---|---|
| Forwarder | Escuta em 127.0.0.1:8899, adiciona Proxy-Authorization, retransmite para gw.crawlrelay.com:7777 |
| Opção Chrome | --proxy-server=http://127.0.0.1:8899 |
| Rotação | Cada novo túnel CONNECT é uma nova conexão, normalmente uma nova saída; adicione um ID de sessão para um IP |
| Alternativa mais simples | Playwright aceita diretamente o nome de usuário e senha |
Como funciona o encaminhador local?
Ele aceita a solicitação de proxy do navegador, insere um cabeçalho com suas credenciais e então copia bytes em ambas as direções. Para um site HTTPS, o navegador envia CONNECT host:443, o gateway responde 200 Connection established, e o TLS roda de ponta a ponta entre o Chrome e o site. O encaminhador nunca vê o conteúdo da página em texto claro.
Esta versão minimalista lida com sites HTTPS, onde cada conexão transporta um túnel CONNECT. Isso cobre quase todos os sites hoje. Mantenha-o ligado ao 127.0.0.1 para que nenhuma outra máquina possa usar suas credenciais.
import asyncio
import base64
import os
UPSTREAM = ("gw.crawlrelay.com", 7777)
USER = os.environ.get("CRAWLRELAY_USER", "USERNAME-country-us")
PASSWORD = os.environ.get("CRAWLRELAY_PASSWORD", "PASSWORD")
AUTH = b"Proxy-Authorization: Basic " + base64.b64encode(("%s:%s" % (USER, PASSWORD)).encode())
async def pipe(reader, writer):
try:
while True:
data = await reader.read(65536)
if not data:
break
writer.write(data)
await writer.drain()
except ConnectionError:
pass
finally:
writer.close()
async def handle(client_reader, client_writer):
try:
head = await client_reader.readuntil(b"\r\n\r\n") # request line and headers from the browser
except asyncio.IncompleteReadError:
client_writer.close()
return
lines = head.split(b"\r\n")
lines.insert(1, AUTH) # add the credentials right after the request line
up_reader, up_writer = await asyncio.open_connection(*UPSTREAM)
up_writer.write(b"\r\n".join(lines))
await up_writer.drain()
await asyncio.gather(pipe(client_reader, up_writer), pipe(up_reader, client_writer))
async def main():
server = await asyncio.start_server(handle, "127.0.0.1", 8899)
async with server:
await server.serve_forever()
if __name__ == "__main__":
asyncio.run(main())Como direciono o Selenium para o encaminhador?
Inicie forwarder.py em um terminal, depois execute seu script Selenium com o endereço do proxy local. O Selenium Manager, integrado ao Selenium 4.6 e posterior, baixa um ChromeDriver correspondente, então não é necessário instalar mais nada.
from selenium import webdriver
from selenium.webdriver.common.by import By
options = webdriver.ChromeOptions()
options.add_argument("--proxy-server=http://127.0.0.1:8899") # the local forwarder
options.add_argument("--headless=new")
driver = webdriver.Chrome(options=options)
try:
driver.set_page_load_timeout(60)
driver.get("https://api.ipify.org")
print("exit IP:", driver.find_element(By.TAG_NAME, "body").text)
finally:
driver.quit()Como obter um IP por sessão Selenium, ou um novo IP por página?
O encaminhador envia o que você der como nome de usuário, então o comportamento da sessão vem desse nome:
- Rotação por conexão: deixe de fora a parte da sessão (
USERNAME-country-us). O Chrome abre várias conexões por página, então uma única página pode carregar por várias saídas. - Um IP por sessão Selenium: defina
CRAWLRELAY_USERcomoUSERNAME-country-us-session-run42-ttl-30antes de iniciar o encaminhador. Cada conexão usa o mesmo IP por até 30 minutos; o IP pode mudar antes. - Várias sessões em paralelo: execute um encaminhador por sessão em portas locais diferentes, como 8899 e 8900, e dê a cada WebDriver sua própria porta.
E quanto ao selenium-wire ou extensões de navegador?
selenium-wire, um pacote popular que adicionava autenticação de proxy interceptando tráfego, foi arquivado por seu autor em janeiro de 2024 e não recebe mais atualizações. Uma extensão de navegador que responde à solicitação de autenticação do proxy também funciona, mas deve ser empacotada e carregada em cada perfil. O encaminhador acima não tem dependências e funciona com qualquer navegador controlado pelo Selenium. Para projetos novos, Playwright é ainda mais simples: ele aceita diretamente o nome de usuário e senha do proxy.
Selenium e proxies: perguntas
Por que o Chrome mostra um pop-up de login com meu proxy no Selenium?
Porque o proxy pediu credenciais e o Chrome não tinha: sua flag --proxy-server aceita apenas um host e porta. No modo headless o mesmo problema aparece como ERR_TUNNEL_CONNECTION_FAILED. Use um encaminhador local que adicione as credenciais ou mude para Playwright, que aceita usuário e senha.
O encaminhador diminui a velocidade da minha raspagem?
Quase nada. Ele copia bytes entre dois sockets locais e um remoto, sem descriptografar nada. O tempo que uma página leva depende da saída residencial e do site alvo, não do encaminhador rodando na mesma máquina.
Posso usar Firefox em vez do Chrome com Selenium?
Sim. Configure as preferências de proxy do Firefox via FirefoxOptions: defina network.proxy.type como 1, e network.proxy.http e network.proxy.ssl como 127.0.0.1 na porta 8899. Mantenha o encaminhador na frente: o Firefox solicita as credenciais do proxy em um diálogo que o Selenium também não consegue preencher confiavelmente.
Minha senha está segura no encaminhador?
Ela fica na sua máquina enquanto o encaminhador escutar em 127.0.0.1, como no exemplo. Leia-a de variáveis de ambiente, nunca a envie para repositórios e use um subusuário dedicado com limite de tráfego para cada scraper, para que uma senha vazada não esgote todo o seu plano.
Dê ao Selenium uma saída residencial
US$ 1,50 para 1 GB para testar, US$ 0,50/GB a partir de 50 GB.