v1.10.90-0e025b8
Skip to main content
TutorialSelenium

Selenium Proxy Configuration: Python and Java Examples

12 min read

By Hex Proxies Engineering Team

Selenium Proxy Configuration: Python and Java Examples

Last updated: April 2026 | Author: Hex Proxies Team

TL;DR: Configure Selenium with proxies in Python (selenium 4.x) and Java using Chrome, Firefox, and Edge. Covers authenticated proxies via extensions, SOCKS5, rotating residential IPs, and headless mode. All examples use Hex Proxies gateway at gate.hexproxies.com:8080. Residential bandwidth starts at $1.70/GB.

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

PracticeWhy It MattersImplementation
Always quit the driverPrevents resource leaks and orphaned browser processesUse try/finally or context managers
Set page load timeoutsPrevents hanging on slow proxied connectionsdriver.set_page_load_timeout(30)
Verify proxy is workingCatches configuration errors earlyFirst request to httpbin.org/ip
Rotate user agentsPrevents fingerprint-based detectionRandom UA per session
Block unnecessary resourcesReduces bandwidth and improves speedBlock images, fonts via CDP
Handle WebDriver exceptionsProxy timeouts cause WebDriver errorsCatch 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.