How to use a proxy that needs a username and password in Selenium, with Chrome or Firefox, headless or not, without browser extensions and without Selenium Wire.
Selenium can point a browser at a proxy, but not log in to it:
--proxy-server=http://user:pass@host:portis ignored by Chrome: it drops the credentials and the proxy answers407.- Firefox preferences have no field for a proxy password.
- The usual workarounds break: a Chrome extension that answers the login has to be packed and loaded and fails in some headless setups, and Selenium Wire is no longer maintained.
proxy_forwarder.py (about 140 lines, standard library only) listens on 127.0.0.1 without authentication and passes every request to the real proxy with the Proxy-Authorization header added. The browser talks to a proxy that needs no password; the forwarder logs in for it.
Chrome / Firefox -> 127.0.0.1:<port> (no auth) -> resi.fusionproxy.net:12286 (with auth) -> website
HTTPS stays end-to-end encrypted: the forwarder only opens the CONNECT tunnel and copies bytes, it never sees the page content.
from selenium import webdriver
from proxy_forwarder import ProxyForwarder
with ProxyForwarder("resi.fusionproxy.net", 12286, "USERNAME-country-us", "PASSWORD") as fwd:
options = webdriver.ChromeOptions()
options.add_argument("--headless=new")
options.add_argument(f"--proxy-server=http://127.0.0.1:{fwd.port}")
driver = webdriver.Chrome(options=options)
driver.get("https://ipinfo.io/json")
print(driver.page_source)
driver.quit()Full script: selenium_chrome.py
options = webdriver.FirefoxOptions()
options.add_argument("-headless")
options.set_preference("network.proxy.type", 1)
options.set_preference("network.proxy.http", "127.0.0.1")
options.set_preference("network.proxy.http_port", fwd.port)
options.set_preference("network.proxy.ssl", "127.0.0.1")
options.set_preference("network.proxy.ssl_port", fwd.port)
driver = webdriver.Firefox(options=options)Full script: selenium_firefox.py
A page loads many resources over many connections. On a rotating proxy each connection could get a different IP, which sites notice. The examples add a sticky session to the username, so the whole browser keeps one residential IP:
session_user = f"{USER}-country-us-sessid-{random.randint(1000000, 9999999)}-sessTime-600s"For several browsers at once, start one forwarder per browser with its own session ID: several_browsers.py runs a US, a German and a British browser in parallel. The username options are explained in the endpoint generator guide.
pip install -r requirements.txt
export FUSION_USER="your_username" # from the Fusion Proxy dashboard
export FUSION_PASS="your_password"
python selenium_chrome.pySelenium 4.6+ downloads the matching driver by itself (Selenium Manager); Chrome or Firefox must be installed.
The forwarder also runs on its own, for any tool that cannot send proxy credentials:
PORT=8899 python proxy_forwarder.py
# then point the tool at http://127.0.0.1:8899| Option | Good for | Catch |
|---|---|---|
| Local forwarder (this repo) | Any browser, headless, CI, parallel browsers | One small extra file |
| IP whitelisting in the proxy dashboard | Fixed servers | Works only from the whitelisted IP; no username, so no per-browser options |
Chrome extension that answers onAuthRequired |
Visible Chrome | Packaging, Chrome only, unreliable headless |
| Playwright or Puppeteer | New projects | Both take proxy credentials natively |
pip install -r requirements.txt pytest
pytestThe tests run the forwarder against a local fake upstream proxy: plain HTTP and CONNECT tunnels get the credentials, a 407 from the upstream reaches the browser, and an unreachable upstream gives 502. No network, proxy or credentials needed.
- playwright-proxy and puppeteer-proxy: browser automation with built-in proxy auth
- python-requests-proxy: proxies in Python requests
- proxy-checker: test proxies before you use them
Need residential IPs? Fusion Proxy residential proxies start at $2.95/GB, with a free trial.
MIT, see LICENSE.