Heto ang bitag na nahuhulog ang bawat browser-automation developer nang eksaktong isang beses: idinaragdag mo ang --proxy-server=http://user:pass@host:port sa launch flags ng Chrome, maayos na nag-start ang browser, at pagkatapos bawat pahina ay nakabitin sa authentication popup na hindi makita o ma-click ng iyong script. Tahimik na tinatanggal ng Chrome ang credentials mula sa proxy flag. Walang error, walang log line, isang modal dialog lang sa browser na walang nagbabantay.
Ang gabay na ito ay ang kumpletong mapa ng mga proxy authentication method na talagang gumagana sa Selenium at Playwright sa 2026 — kung alin ang gagamitin, kung alin ang iiwasan, at ang eksaktong code para sa bawat isa. (Para sa proxy selection at rotation strategy sa mga tool na ito, tingnan ang Using Proxies with Playwright & Puppeteer — ang artikulong ito ay puro tungkol sa pagpapadaan ng credentials.)
Pina-parse ng mga command-line HTTP client ang credentials mula sa proxy URL at awtomatikong sinasagot ang 407 Proxy Authentication Required ng proxy gamit ang Proxy-Authorization header. Hindi ito ginagawa ng Chromium: tinatanggap lang ng --proxy-server ang scheme://host:port, at kapag bumalik ang 407 ay nagpapakita ito ng interactive dialog. Sa headless mode wala man lang dialog — nabibigo lang ang request.
Kaya ang tanong ay hindi kailanman "paano ko ilalagay ang password sa URL" — ito ay "aling layer ang sasagot sa 407 para sa akin." Apat na gumaganang sagot, pinakamaganda muna.
Maayos na nalutas ng Playwright ang problema: sinasagot nito mismo ang mga proxy auth challenge sa pamamagitan ng CDP. Napupunta ang credentials sa launch o context options:
# Python
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(
proxy={
"server": "http://us.jibaoproxy.com:913",
"username": "USERNAME-session-job1",
"password": "PASSWORD",
}
)
// Node.js - and per-context, which is where it gets powerful:
const browser = await chromium.launch({
proxy: { server: 'per-context' } // declare intent at launch
});
const ctx = await browser.newContext({
proxy: {
server: 'http://us.jibaoproxy.com:913',
username: 'USERNAME-session-job2',
password: 'PASSWORD',
}
});
Ang per-context proxies ay nangangahulugang ang isang browser process ay makakapagpatakbo ng N context sa N magkakaibang sticky session — ang pundasyon ng bawat seryosong Playwright scraping setup. Kung nasa Playwright ka, tapos ka na; lumaktaw sa verification section. Umiiral ang lahat ng nasa ibaba dahil walang katumbas ang Selenium.
Binabalot ng selenium-wire ang Selenium ng local MITM proxy na hina-handle ang upstream authentication:
from seleniumwire import webdriver # pip install selenium-wire
options = {
"proxy": {
"http": "http://USERNAME:[email protected]:913",
"https": "https://USERNAME:[email protected]:913",
}
}
driver = webdriver.Chrome(seleniumwire_options=options)
driver.get("https://example.com")
Mga caveat na dapat mong malaman bago ang production:
Ang klasikong approach: isang maliit na generated extension na nagtatakda ng proxy at sumasagot sa auth sa pamamagitan ng chrome.webRequest.onAuthRequired. Walang MITM, walang extrang process, gumagana sa simpleng Selenium:
import zipfile, json
HOST, PORT = "us.jibaoproxy.com", 913
USER, PASS = "USERNAME-session-sel1", "PASSWORD"
manifest = {
"version": "1.0.0", "manifest_version": 2, "name": "Proxy Auth",
"permissions": ["proxy", "webRequest", "webRequestBlocking", ""],
"background": {"scripts": ["background.js"]},
}
background = f"""
chrome.proxy.settings.set({{value: {{mode: "fixed_servers", rules: {{
singleProxy: {{scheme: "http", host: "{HOST}", port: {PORT}}}
}}}}, scope: "regular"}}, () => {{}});
chrome.webRequest.onAuthRequired.addListener(
() => ({{authCredentials: {{username: "{USER}", password: "{PASS}"}}}}),
{{urls: [""]}}, ["blocking"]
);
"""
with zipfile.ZipFile("proxy_auth.zip", "w") as zp:
zp.writestr("manifest.json", json.dumps(manifest))
zp.writestr("background.js", background)
from selenium import webdriver
opts = webdriver.ChromeOptions()
opts.add_extension("proxy_auth.zip")
driver = webdriver.Chrome(options=opts)
Dalawang gotcha: hindi nag-loload ang mga extension sa classic headless mode — gamitin ang --headless=new (Chrome 109+) o magpatakbo nang headed; at gumagana pa rin ang Manifest V2 background scripts para sa sideloaded automation extensions pero bantayan ang MV2 deprecation timeline ng Chrome — ang MV3 na katumbas ay nangangailangan ng service worker at ng parehong onAuthRequired listener.
Magpatakbo ng maliit na local proxy na may hawak ng credentials; ituro ang browser sa localhost nang walang auth man lang. Gumagana sa bawat browser, bawat driver, bawat wika, headless man o hindi:
# Using pproxy (pip install pproxy) - terminal 1:
pproxy -l http://127.0.0.1:8899 \
-r "http://USERNAME:[email protected]:913"
# Your script - terminal 2: plain Selenium, no auth needed
opts = webdriver.ChromeOptions()
opts.add_argument("--proxy-server=http://127.0.0.1:8899")
driver = webdriver.Chrome(options=opts)
Ito rin ang pinakamalinis na sagot para sa Firefox/geckodriver (kung saan hindi gumagana ang extension trick) at para sa mga exotic na environment tulad ng Electron app testing. Halaga: isa pang gumagalaw na bahagi na susubaybayan, at ang per-context routing ay nangangailangan ng isang forwarder port kada session.
| Method | Gumagana sa | Headless | Per-context sessions | Hatol sa production |
|---|---|---|---|---|
| Playwright native | Playwright | Oo | Oo | Default na pagpipilian |
| selenium-wire | Selenium (Py) | Oo | Per-driver | Okay sa katamtamang scale |
| Auth extension | Selenium (anumang wika) | --headless=new lang | Per-driver | Matibay, bantayan ang MV3 |
| Local forwarder | Lahat | Oo | Isang port kada session | Unibersal na fallback |
Ang tahimik na pagbalik sa iyong totoong IP ang failure mode na nagpapa-ban ng mga account. I-assert ang exit IP sa simula ng bawat run:
ip = driver.execute_script(
"return fetch('https://api.ipify.org').then(r => r.text())"
) if hasattr(driver, 'execute_script') else page.evaluate(
"fetch('https://api.ipify.org').then(r => r.text())"
)
assert ip != MY_REAL_IP, "Proxy not applied - aborting before we leak"
--proxy-server; tinanggal ng Chrome. Gamitin ang isa sa apat na method.ERR_PROXY_CONNECTION_FAILED — mali ang host/port o protocol mismatch. I-test ang parehong linya gamit ang curl -x muna; kung gumagana ang curl, nasa browser wiring mo ang problema.--headless=new.Hindi binabasa ng mga browser ang user:pass@ na proxy URL — may kailangang sumagot sa 407 para sa kanila. Sa Playwright, ang bagay na iyon ay built in; sa Selenium ito ay selenium-wire, isang generated auth extension, o isang local forwarder. Pumili ayon sa iyong stack mula sa comparison table, tapos i-assert ang exit IP sa bawat run para hindi kailanman ma-leak ng tahimik na auth failure ang iyong totoong address sa kalagitnaan ng crawl.
500MB free residential traffic — isang gateway, sticky o rotating, HTTP at SOCKS5.
Start Free TrialAng mga bagong user ay makakatanggap ng 500MB sa pagrehistro, kasama ang bonus sa unang recharge. Limitadong oras lang ang alok.