Selenium and proxies: the basics
Selenium drives real browsers through the WebDriver protocol. Setting a proxy without authentication is simple. Authenticated proxies, which most paid providers use, are where Selenium is less convenient than Puppeteer or Playwright. This guide covers both.
Chrome without authentication (Python)
from selenium import webdriver
opts = webdriver.ChromeOptions()
opts.add_argument("--proxy-server=http://203.0.113.10:8080")
driver = webdriver.Chrome(options=opts)
driver.get("https://httpbin.org/ip")
print(driver.find_element("tag name", "body").text)
driver.quit()This works for IP-whitelisted proxies and SOCKS5 (socks5://host:port).
Firefox without authentication (Python)
from selenium import webdriver
opts = webdriver.FirefoxOptions()
opts.set_preference("network.proxy.type", 1)
opts.set_preference("network.proxy.http", "203.0.113.10")
opts.set_preference("network.proxy.http_port", 8080)
opts.set_preference("network.proxy.ssl", "203.0.113.10")
opts.set_preference("network.proxy.ssl_port", 8080)
driver = webdriver.Firefox(options=opts)For SOCKS in Firefox, set network.proxy.socks, network.proxy.socks_port, network.proxy.socks_version (5) and network.proxy.socks_remote_dns (True).
Authenticated proxies: your options
Chrome ignores credentials in --proxy-server, and Selenium has historically had no simple API for proxy authentication. Options:
1. IP whitelisting (simplest)
Whitelist your machine's IP with the provider and use the plain --proxy-server flag. See proxy authentication methods.
2. A local forwarder
Run a small local proxy that adds credentials and forwards upstream, then point Selenium at it. For example, with gost:
gost -L http://127.0.0.1:8080 -F http://USER:PASS@gate.example.com:7777opts.add_argument("--proxy-server=http://127.0.0.1:8080")This keeps Selenium code simple and works for any browser. It's also the most robust option for rotating providers, because you can restart the forwarder with a new session username.
3. A Chrome extension that supplies credentials
A small Manifest V3 extension can configure the proxy and respond to onAuthRequired events. It works, but extensions need maintenance as Chrome changes, and headless mode support for extensions depends on the Chrome version.
4. Libraries that intercept traffic
Selenium Wire was popular for this, but the project has been archived and is no longer maintained, so it's best avoided for new projects. Selenium 4's BiDi features are also adding network interception and authentication handling; check the current Selenium documentation for your language binding.
Rotating proxies with Selenium
Selenium can't change a running browser's proxy. To rotate, start a new driver (or restart the local forwarder with a new upstream/session) for each session:
import uuid
from selenium import webdriver
def driver_for_session():
# assumes a local forwarder whose upstream you set per session, or a whitelisted rotating gateway
opts = webdriver.ChromeOptions()
opts.add_argument("--proxy-server=http://gate.example.com:7777") # whitelisted gateway, rotates per connection
opts.add_argument("--lang=en-US")
return webdriver.Chrome(options=opts)For per-session sticky IPs with credentials, the forwarder approach is the cleanest. See proxy rotation strategies.
Reduce detection
Selenium-driven Chrome exposes navigator.webdriver and other signals. Projects like undetected-chromedriver attempt to patch these. Combine with matching locale and timezone for your proxy. See browser fingerprinting and proxies.
Java example (no auth)
ChromeOptions options = new ChromeOptions();
options.addArguments("--proxy-server=http://203.0.113.10:8080");
WebDriver driver = new ChromeDriver(options);
driver.get("https://httpbin.org/ip");Proxy tip: Want to skip proxy management on some targets? Geonode offers both raw proxies and a Scraper API that returns HTML or Markdown with optional JavaScript rendering. We compare the two approaches in using Geonode with Selenium.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| Auth popup or 407 | Credentials not supplied | Whitelist, forwarder or extension |
ERR_PROXY_CONNECTION_FAILED | Wrong host/port/scheme | Check settings |
| Real IP shown | Proxy not applied (typo, wrong preference) | Verify with an IP echo page |
| WebRTC shows real IP | WebRTC leak | See WebRTC leaks |
Running a local forwarder from Python
You can start a forwarder process from your Python script so Selenium always uses an authenticated upstream without credentials in the browser:
import subprocess, time, uuid
from selenium import webdriver
def start_forwarder(local_port, upstream):
# requires gost installed; starts a local HTTP proxy forwarding to the authenticated upstream
return subprocess.Popen(["gost", "-L", f"http://127.0.0.1:{local_port}", "-F", upstream])
sid = uuid.uuid4().hex[:8]
fwd = start_forwarder(18080, f"http://customer-USER-session-{sid}:PASS@gate.example.com:7777")
time.sleep(1)
try:
opts = webdriver.ChromeOptions()
opts.add_argument("--proxy-server=http://127.0.0.1:18080")
driver = webdriver.Chrome(options=opts)
driver.get("https://httpbin.org/ip")
print(driver.find_element("tag name", "body").text)
driver.quit()
finally:
fwd.terminate()Use a different local port per parallel session.
Selenium Grid and proxies
On Selenium Grid, each node's browser gets its proxy from the capabilities you send. For per-session proxies, pass the proxy argument per session; for authenticated proxies, run forwarders on the nodes or use whitelisted proxies.
Matching locale and timezone
Chrome flags such as --lang=en-GB set language. Timezone can be set via the TZ environment variable for the browser process on Linux, or through Chrome DevTools Protocol commands in Selenium 4 (Emulation.setTimezoneOverride). Match these to the proxy's location. See browser fingerprinting and proxies.
Which proxy type for Selenium testing?
For QA testing your own sites from different regions, datacenter proxies are usually enough and cheapest. For testing how real users in a region experience third-party content (ads, geo-redirects), use residential proxies.
Verifying the proxy from inside the session
The most reliable check is the one the browser makes itself, inside the same session that will do the work. Add a quick self-test at the start of each run:
driver.get("https://api.ipify.org?format=json")
print("exit IP:", driver.find_element("tag name", "body").text)
tz, lang = driver.execute_script(
"return [Intl.DateTimeFormat().resolvedOptions().timeZone, navigator.language]"
)
print("timezone:", tz, "language:", lang)What you're looking for:
- The exit IP is the proxy's, not your server's. If it's your own IP, the proxy option didn't apply, often because of a typo in the argument or a driver that ignored it.
- The timezone and language fit the proxy's location. A browser reporting
America/New_Yorkbehind a German IP is an easy inconsistency for sites to spot. - The check passes in every new driver, not just the first one. Long runs that create drivers in a loop can drift from the configuration you tested.
For a fuller check, open a WebRTC leak test in the same session; see WebRTC leaks and proxies. For aligning locale and timezone with the proxy, see browser fingerprinting and proxies, and for the general method, how to check if a proxy works. Selenium's own browser options documentation shows the proxy capability for each language binding.
Key takeaways
- Unauthenticated proxies are simple in Selenium:
--proxy-serverfor Chrome, network preferences for Firefox. - Chrome ignores credentials in the proxy flag; use IP whitelisting, a local forwarder such as gost, or a maintained extension.
- Selenium Wire is archived; prefer forwarders or Selenium 4's evolving network features for new projects.
- To rotate IPs, start a new driver or restart the forwarder with a new upstream session.
- Match language and timezone to the proxy and guard against WebRTC leaks. See webrtc leaks and proxies.
FAQ
Is Selenium good for scraping with proxies?
It works, but Playwright and Puppeteer offer more convenient proxy handling. Selenium remains strong for cross-browser testing.
Can Selenium use SOCKS5 with authentication?
Not directly in Chrome. Use whitelisting or a forwarder.
Which proxies are best for Selenium?
The same as for other browsers: residential sticky sessions for protected sites, ISP for logged-in flows. See best proxies for web scraping.
Editorial note: Proxy providers change their pools, features and prices often, so treat any figures here as typical ranges at the time of writing and confirm current terms with the provider before you buy.