Web Scraping & Automation

Selenium Proxies: Setup, Authentication and Rotation

How to configure proxies in Selenium for Chrome and Firefox, handle authenticated proxies (whitelisting, local forwarders, extensions), rotate IPs, and avoid common pitfalls.

By Team of Monkeys Editorial Updated 4 min read Affiliate disclosure

This guide contains affiliate links to Geonode. If you buy through them we may earn a commission, at no extra cost to you.

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)

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)

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:

bash
gost -L http://127.0.0.1:8080 -F http://USER:PASS@gate.example.com:7777
python
opts.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:

python
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)

java
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

SymptomCauseFix
Auth popup or 407Credentials not suppliedWhitelist, forwarder or extension
ERR_PROXY_CONNECTION_FAILEDWrong host/port/schemeCheck settings
Real IP shownProxy not applied (typo, wrong preference)Verify with an IP echo page
WebRTC shows real IPWebRTC leakSee 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:

python
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:

python
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_York behind 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-server for 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.

Affiliate disclosure: Team of Monkeys is a Geonode affiliate. Links and banners marked as sponsored, and links to Geonode in the text, use our referral link, and we may earn a commission if you buy through them, at no extra cost to you. Our explanations and comparisons are written to be useful whichever provider you choose.

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.