Selenium Proxy Configuration: Python and Java Examples
Last updated: April 2026 | Author: Hex Proxies Team
Selenium remains one of the most widely used browser automation frameworks in 2026, and proxy configuration is essential for any serious automation workload. This guide provides production-ready code for configuring proxies in Selenium with Python and Java, covering authenticated proxies, rotation strategies, and common pitfalls.
Quick Start: Basic Proxy Configuration
Python with Chrome
The simplest proxy setup in Selenium Python uses Chrome options to set the proxy server:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = Options()
options.add_argument("--proxy-server=http://gate.hexproxies.com:8080")
driver = webdriver.Chrome(options=options)
driver.get("https://httpbin.org/ip")
print(driver.find_element("tag name", "body").text)
driver.quit()
This works for proxies that do not require authentication. For authenticated proxies (which most commercial providers use), you need a different approach.
Java with Chrome
import org.openqa.selenium.Proxy;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
public class BasicProxySetup {
public static void main(String[] args) {
Proxy proxy = new Proxy();
proxy.setHttpProxy("gate.hexproxies.com:8080");
proxy.setSslProxy("gate.hexproxies.com:8080");
ChromeOptions options = new ChromeOptions();
options.setProxy(proxy);
WebDriver driver = new ChromeDriver(options);
driver.get("https://httpbin.org/ip");
System.out.println(driver.getPageSource());
driver.quit();
}
}
Authenticated Proxy Configuration
Most proxy providers, including Hex Proxies, require username/password authentication. Selenium does not natively support proxy authentication, so you need workarounds depending on your language and browser.
Python: Chrome Extension Method (Recommended)
The most reliable method for authenticated proxies in Chrome is creating a temporary extension that injects credentials:
import os
import zipfile
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
def create_proxy_extension(proxy_host, proxy_port, proxy_user, proxy_pass):
"""Create a Chrome extension for proxy authentication."""
manifest_json = """{
"version": "1.0.0",
"manifest_version": 2,
"name": "Proxy Auth",
"permissions": ["proxy", "tabs", "unlimitedStorage", "storage",
"<all_urls>", "webRequest", "webRequestBlocking"],
"background": {"scripts": ["background.js"]}
}"""
background_js = """var config = {
mode: "fixed_servers",
rules: {
singleProxy: {
scheme: "http",
host: "%s",
port: %d
},
bypassList: ["localhost"]
}
};
chrome.proxy.settings.set({value: config, scope: "regular"}, function() {});
function callbackFn(details) {
return {
authCredentials: {
username: "%s",
password: "%s"
}
};
}
chrome.webRequest.onAuthRequired.addListener(
callbackFn,
{urls: ["<all_urls>"]},
['blocking']
);""" % (proxy_host, proxy_port, proxy_user, proxy_pass)
extension_path = "/tmp/proxy_auth_extension.zip"
with zipfile.ZipFile(extension_path, "w") as zp:
zp.writestr("manifest.json", manifest_json)
zp.writestr("background.js", background_js)
return extension_path
# Configure with Hex Proxies
extension = create_proxy_extension(
proxy_host="gate.hexproxies.com",
proxy_port=8080,
proxy_user="YOUR_USERNAME-country-us",
proxy_pass="YOUR_PASSWORD"
)
options = Options()
options.add_extension(extension)
driver = webdriver.Chrome(options=options)
driver.get("https://httpbin.org/ip")
print(driver.find_element("tag name", "body").text)
driver.quit()
# Clean up
os.remove(extension)
Note: The extension method does not work in headless mode with older Chrome versions. Chrome 109+ supports extensions in the new headless mode (--headless=new).
Python: Selenium Wire Method
Selenium Wire is a drop-in replacement for Selenium that adds proxy authentication support natively:
from seleniumwire import webdriver
options = {
"proxy": {
"http": "http://YOUR_USERNAME-country-us:YOUR_PASSWORD@gate.hexproxies.com:8080",
"https": "http://YOUR_USERNAME-country-us:YOUR_PASSWORD@gate.hexproxies.com:8080",
"no_proxy": "localhost,127.0.0.1"
}
}
driver = webdriver.Chrome(seleniumwire_options=options)
driver.get("https://httpbin.org/ip")
print(driver.find_element("tag name", "body").text)
driver.quit()
Selenium Wire intercepts requests at the network level, making it compatible with headless mode and all browser types.
Java: Authenticated Proxy with CDP
In Java, use Chrome DevTools Protocol (CDP) for proxy authentication:
import org.openqa.selenium.Proxy;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.v124.fetch.Fetch;
import org.openqa.selenium.devtools.v124.fetch.model.HeaderEntry;
import java.util.Base64;
import java.util.List;
import java.util.Optional;
public class AuthenticatedProxy {
public static void main(String[] args) {
Proxy proxy = new Proxy();
proxy.setHttpProxy("gate.hexproxies.com:8080");
proxy.setSslProxy("gate.hexproxies.com:8080");
ChromeOptions options = new ChromeOptions();
options.setProxy(proxy);
ChromeDriver driver = new ChromeDriver(options);
DevTools devTools = driver.getDevTools();
devTools.createSession();
// Handle proxy authentication via CDP
devTools.send(Fetch.enable(
Optional.empty(),
Optional.of(true) // handleAuthRequests
));
devTools.addListener(Fetch.authRequired(), authRequired -> {
String credentials = Base64.getEncoder().encodeToString(
"YOUR_USERNAME-country-us:YOUR_PASSWORD".getBytes()
);
devTools.send(Fetch.continueWithAuth(
authRequired.getRequestId(),
new org.openqa.selenium.devtools.v124.fetch.model.AuthChallengeResponse(
org.openqa.selenium.devtools.v124.fetch.model.AuthChallengeResponse.Response.PROVIDECREDENTIALS,
Optional.of("YOUR_USERNAME-country-us"),
Optional.of("YOUR_PASSWORD")
)
));
});
devTools.addListener(Fetch.requestPaused(), requestPaused -> {
devTools.send(Fetch.continueRequest(
requestPaused.getRequestId(),
Optional.empty(),
Optional.empty(),
Optional.empty(),
Optional.empty(),
Optional.empty()
));
});
driver.get("https://httpbin.org/ip");
System.out.println(driver.getPageSource());
driver.quit();
}
}
Rotating Proxies in Selenium
Hex Proxies supports automatic IP rotation through the gateway. Each new browser session gets a fresh IP by default. For manual rotation within a session, use session parameters:
Per-Request Rotation (New Browser per Request)
from seleniumwire import webdriver
import time
def scrape_with_rotation(urls):
"""Each URL gets a fresh browser instance with a new IP."""
results = []
for url in urls:
options = {
"proxy": {
"http": "http://YOUR_USERNAME-country-us:YOUR_PASSWORD@gate.hexproxies.com:8080",
"https": "http://YOUR_USERNAME-country-us:YOUR_PASSWORD@gate.hexproxies.com:8080"
}
}
driver = webdriver.Chrome(seleniumwire_options=options)
try:
driver.get(url)
time.sleep(2) # Wait for content
results.append({
"url": url,
"title": driver.title,
"content": driver.page_source
})
except Exception as e:
results.append({"url": url, "error": str(e)})
finally:
driver.quit()
time.sleep(1) # Brief pause between requests
return results
Sticky Session (Same IP for Multiple Pages)
from seleniumwire import webdriver
import time
def scrape_with_sticky_session(urls, session_id="mysession"):
"""All URLs use the same IP via sticky session."""
options = {
"proxy": {
"http": f"http://YOUR_USERNAME-country-us-session-{session_id}:YOUR_PASSWORD@gate.hexproxies.com:8080",
"https": f"http://YOUR_USERNAME-country-us-session-{session_id}:YOUR_PASSWORD@gate.hexproxies.com:8080"
}
}
driver = webdriver.Chrome(seleniumwire_options=options)
results = []
try:
for url in urls:
driver.get(url)
time.sleep(2)
results.append({
"url": url,
"title": driver.title
})
finally:
driver.quit()
return results
Browser-Specific Configuration
Firefox with Proxy Profile
from selenium import webdriver
from selenium.webdriver.firefox.options import Options
options = Options()
options.set_preference("network.proxy.type", 1)
options.set_preference("network.proxy.http", "gate.hexproxies.com")
options.set_preference("network.proxy.http_port", 8080)
options.set_preference("network.proxy.ssl", "gate.hexproxies.com")
options.set_preference("network.proxy.ssl_port", 8080)
options.set_preference("network.proxy.no_proxies_on", "localhost,127.0.0.1")
driver = webdriver.Firefox(options=options)
driver.get("https://httpbin.org/ip")
print(driver.find_element("tag name", "body").text)
driver.quit()
Note: Firefox handles proxy authentication via a popup dialog. For automated authentication, use the Selenium Wire approach or an extension.
Edge with Proxy
from selenium import webdriver
from selenium.webdriver.edge.options import Options
options = Options()
options.add_argument("--proxy-server=http://gate.hexproxies.com:8080")
driver = webdriver.Edge(options=options)
driver.get("https://httpbin.org/ip")
print(driver.find_element("tag name", "body").text)
driver.quit()
SOCKS5 Proxy Configuration
For use cases requiring SOCKS5 (UDP support, DNS resolution through proxy), configure Selenium with SOCKS proxy settings:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = Options()
options.add_argument("--proxy-server=socks5://gate.hexproxies.com:1080")
# Ensure DNS resolves through the proxy (prevents DNS leaks)
options.add_argument("--host-resolver-rules=MAP * ~NOTFOUND, EXCLUDE localhost")
driver = webdriver.Chrome(options=options)
driver.get("https://httpbin.org/ip")
print(driver.find_element("tag name", "body").text)
driver.quit()
For a comparison of HTTP vs SOCKS5 proxy protocols, see our protocol comparison guide.
Headless Mode with Proxies
Running Selenium in headless mode with proxies requires attention to Chrome version differences:
from seleniumwire import webdriver
from selenium.webdriver.chrome.options import Options
chrome_options = Options()
# Use the new headless mode (Chrome 109+) which supports extensions
chrome_options.add_argument("--headless=new")
chrome_options.add_argument("--no-sandbox")
chrome_options.add_argument("--disable-dev-shm-usage")
chrome_options.add_argument("--window-size=1920,1080")
# Set a realistic user agent
chrome_options.add_argument(
"user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36"
)
seleniumwire_options = {
"proxy": {
"http": "http://YOUR_USERNAME-country-us:YOUR_PASSWORD@gate.hexproxies.com:8080",
"https": "http://YOUR_USERNAME-country-us:YOUR_PASSWORD@gate.hexproxies.com:8080"
}
}
driver = webdriver.Chrome(
options=chrome_options,
seleniumwire_options=seleniumwire_options
)
driver.get("https://httpbin.org/ip")
print(driver.find_element("tag name", "body").text)
driver.quit()
Production Best Practices
| Practice | Why It Matters | Implementation |
|---|---|---|
| Always quit the driver | Prevents resource leaks and orphaned browser processes | Use try/finally or context managers |
| Set page load timeouts | Prevents hanging on slow proxied connections | driver.set_page_load_timeout(30) |
| Verify proxy is working | Catches configuration errors early | First request to httpbin.org/ip |
| Rotate user agents | Prevents fingerprint-based detection | Random UA per session |
| Block unnecessary resources | Reduces bandwidth and improves speed | Block images, fonts via CDP |
| Handle WebDriver exceptions | Proxy timeouts cause WebDriver errors | Catch TimeoutException, WebDriverException |
Troubleshooting Common Issues
ERR_TUNNEL_CONNECTION_FAILED
This error means the proxy server rejected the CONNECT request. Common causes: incorrect credentials, expired subscription, or firewall blocking the proxy port. Verify your credentials work with a simple curl test: curl -x http://USER:PASS@gate.hexproxies.com:8080 https://httpbin.org/ip
Proxy Authentication Dialog Appears
If a browser dialog pops up asking for proxy credentials, your authentication method is not working. Switch to the Chrome extension method or Selenium Wire. The --proxy-server flag does not support inline credentials.
Slow Page Loads Through Proxy
Proxied requests add latency (typically 100-500ms). If pages are loading very slowly, check: (1) proxy server location relative to target — use a proxy in the same region as the target, (2) bandwidth limits on your plan, (3) concurrent connection limits.
SSL Certificate Errors
Some proxy configurations cause SSL certificate warnings. If you see certificate errors, avoid disabling SSL verification in production. Instead, ensure your proxy supports HTTPS CONNECT tunneling (all Hex Proxies endpoints do).
Frequently Asked Questions
Can I use Selenium with rotating residential proxies?
Yes. With Hex Proxies, connect to gate.hexproxies.com:8080 and each new browser session automatically gets a new IP. For rotation within a session, you need to restart the browser or use the sticky session parameter with different session IDs. See our rotating proxy setup guide for details.
Is Selenium Wire safe for production use?
Selenium Wire intercepts traffic through a local proxy server, which adds a small amount of latency. For production scraping, it is reliable and widely used. However, for maximum performance with thousands of concurrent sessions, consider Playwright or Puppeteer which have native proxy authentication support. See our Puppeteer proxy guide for alternatives.
How do I verify my proxy is working in Selenium?
Navigate to https://httpbin.org/ip as your first request and check that the returned IP address is not your real IP. You can also use https://ipinfo.io/json to verify the geo-location matches your proxy settings.
Does Selenium work with ISP proxies?
Yes. ISP proxies work identically to residential proxies from a Selenium configuration perspective. The difference is that ISP proxies provide a static IP that does not change between sessions. This is ideal for Selenium workflows that require consistent identity, like managing social media accounts or accessing sites that track IP history. ISP proxies at Hex Proxies start at $0.83/IP. See our ISP proxy page for details.