Kort antwoord
Hoe gebruik ik een proxy met gebruikersnaam en wachtwoord in Selenium?
Draai een kleine lokale forwarder die de Proxy-Authorization header toevoegt, en wijs Chrome daarop via --proxy-server=http://127.0.0.1:8899. Chrome negeert inloggegevens in die flag, en Selenium heeft geen draagbare optie voor proxywachtwoorden. CrawlRelay residentiële proxy's werken zo over gw.crawlrelay.com:7777, van US$ 0,50/GB. Betaald in crypto, zonder KYC.
Selenium setup in een oogopslag
| Waarom een forwarder | Chrome's --proxy-server flag accepteert geen gebruikersnaam of wachtwoord |
|---|---|
| Forwarder | Luistert op 127.0.0.1:8899, voegt Proxy-Authorization toe, stuurt door naar gw.crawlrelay.com:7777 |
| Chrome-optie | --proxy-server=http://127.0.0.1:8899 |
| Rotatie | Elke nieuwe CONNECT-tunnel is een nieuwe verbinding, dus meestal een nieuwe exit; voeg een sessie-ID toe voor één IP |
| Eenvoudiger alternatief | Playwright neemt de gebruikersnaam en het wachtwoord rechtstreeks over |
Hoe werkt de lokale forwarder?
Hij accepteert het proxyverzoek van de browser, voegt één header toe met jouw inloggegevens en kopieert vervolgens data in beide richtingen. Voor een HTTPS-site stuurt de browser CONNECT host:443, beantwoordt de gateway met 200 Connection established, en TLS loopt dan end-to-end tussen Chrome en de website. De forwarder ziet de pagina-inhoud nooit in platte tekst.
Deze minimale versie behandelt HTTPS-sites, waarbij elke verbinding één CONNECT-tunnel draagt. Dit dekt bijna iedere website tegenwoordig. Houd hem gebonden aan 127.0.0.1 zodat geen andere machine jouw inloggegevens kan gebruiken.
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())Hoe wijs ik Selenium toe aan de forwarder?
Start forwarder.py in een terminal en voer daarna je Selenium-script uit met het lokale proxyadres. Selenium Manager, ingebouwd in Selenium 4.6 en hoger, downloadt een passende ChromeDriver, dus er hoeft verder niets geïnstalleerd te worden.
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()Hoe krijg ik één IP per Selenium-sessie, of een nieuw IP per pagina?
De forwarder stuurt wat jij als gebruikersnaam geeft, dus het sessiegedrag hangt af van die gebruikersnaam:
- Rotatie per verbinding: laat het sessie-deel weg (
USERNAME-country-us). Chrome opent meerdere verbindingen per pagina, dus een enkele pagina kan via meerdere exit-IP’s laden. - Één IP per Selenium-sessie: zet
CRAWLRELAY_USERopUSERNAME-country-us-session-run42-ttl-30voordat je de forwarder start. Elke verbinding verloopt dan via hetzelfde IP tot 30 minuten; het IP kan ook eerder veranderen. - Meerdere sessies parallel: start voor elke sessie een aparte forwarder op verschillende lokale poorten, bijvoorbeeld 8899 en 8900, en geef elke WebDriver zijn eigen poort.
Hoe zit het met selenium-wire of browserextensies?
selenium-wire, een populair pakket dat proxy-authenticatie toevoegde door verkeer te onderscheppen, is in januari 2024 door de auteur gearchiveerd en krijgt geen updates meer. Een browserextensie die proxy-authenticatie afhandelt werkt ook, maar moet verpakt worden en in elk profiel geladen worden. De hierboven genoemde forwarder heeft geen afhankelijkheden en werkt met elke browser die Selenium aanstuurt. Voor nieuwe projecten is Playwright nog eenvoudiger: die accepteert de proxygebruikersnaam en het wachtwoord direct.
Selenium en proxy's: vragen
Waarom toont Chrome een inlogpop-up met mijn proxy in Selenium?
Omdat de proxy om inloggegevens vroeg en Chrome die niet had: zijn --proxy-server-vlag accepteert alleen een host en poort. In headless mode verschijnt hetzelfde probleem als ERR_TUNNEL_CONNECTION_FAILED. Gebruik een lokale forwarder die de inlog toevoegt, of schakel over naar Playwright, dat gebruikersnaam en wachtwoord accepteert.
Vertraagt de forwarder mijn scraping?
Bijna niet. Hij kopieert alleen bytes tussen twee lokale sockets en één externe, zonder iets te ontsleutelen. De laadtijd van een pagina hangt af van de residentiële exit en de doelwebsite, niet van een forwarder die op dezelfde machine draait.
Kan ik Firefox gebruiken in plaats van Chrome met Selenium?
Ja. Stel de proxyvoorkeuren van Firefox in via FirefoxOptions: zet network.proxy.type op 1, en network.proxy.http en network.proxy.ssl op 127.0.0.1 met poort 8899. Houd de forwarder voor je; Firefox vraagt om proxy-inloggegevens in een dialoog die Selenium ook niet betrouwbaar kan invullen.
Is mijn wachtwoord veilig in de forwarder?
Het blijft op jouw machine zolang de forwarder luistert op 127.0.0.1, zoals in het voorbeeld. Lees het uit omgevingsvariabelen, commit het nooit, en gebruik voor elke scraper een aparte subgebruiker met een datalimiet zodat een gelekt wachtwoord je hele abonnement niet kan opmaken.
Geef Selenium een residentiële exit
US$ 1,50 voor 1 GB om te testen, US$ 0,50/GB vanaf 50 GB.