How to Set Up a Selenium Proxy Server in Python

Learn how to configure an HTTP or SOCKS5 proxy in Selenium with Python, handle proxy authentication, verify routing, and use rotating or static proxy sessions responsibly.

Kevin LinKevin LinSep 10, 202611 min read

TL;DR

Selenium supports HTTP and SOCKS5 proxy routing through ChromeOptions, then you can verify the route in an authorized test environment. For unauthenticated or IP-whitelisted endpoints, pass --proxy-server=http://HOST:PORT or --proxy-server=socks5://HOST:PORT directly into Chromium startup flags. For authenticated HTTP/HTTPS proxies, use the provider’s documented authentication method or a compatible extension workflow. SOCKS5 authentication depends on the browser, proxy implementation, and provider configuration.

When scaling automated data collection or quality assurance, avoid restarting ChromeDriver on every request to change IPs. Instead, route your Selenium instance through an upstream proxy gateway—such as dynamic residential or mobile proxy endpoints—which manages IP rotation or sticky sessions without client-side browser restarts.

selenium-proxy-architecture

Why Use a Proxy Server in Selenium?

Selenium automates real desktop and mobile browser instances, executing JavaScript, rendering CSS, and processing cookies. However, automated browser workflows operating from a single static IP address face operational constraints:

  • Request Rate Management: Web services monitor request frequency by IP address, throttling or blocking automated browser sessions that exceed standard usage thresholds.
  • Geographic Content Verification: E-commerce stores, flight aggregators, and localized search engines deliver localized pricing and layouts based on client IP geolocation.
  • Network Environment Testing: Automated testing suites require verifying application performance across varying network types, such as consumer residential ISPs or cellular carrier networks.
  • Session and State Isolation: Concurrent QA tasks and multi-account testing workflows require distinct network endpoints to prevent cross-session tracking and cache overlap.

Integrating a proxy server alters your browser egress IP, enabling automated test pipelines to emulate connections across different geographic regions and network tiers.

Operational Scope & Limitations: A proxy routes supported connections through an intermediary server. It does not encrypt application traffic by itself, guarantee remote DNS resolution in every client, remove browser automation signals, or override a website’s access controls. Always confirm your client implementation, provider policies, target-site terms of service, and authorized test scope before deployment.

Understanding Selenium Proxy Protocols: HTTP(S) vs. SOCKS5

Choosing the right protocol determines how Selenium establishes tunnels to the intermediary proxy gateway.

Protocol Feature HTTP / HTTPS Proxy SOCKS5 Proxy (RFC 1928)
Protocol Scope Application Layer proxying Generic proxy protocol for TCP/UDP streams
Connection Method CONNECT tunneling for TLS traffic SOCKS handshake establishing a TCP/UDP relay
Traffic Handling Designed primarily for HTTP and HTTPS Relays arbitrary socket traffic supported by the proxy
DNS Resolution Resolved locally or via proxy depending on configuration Resolution behavior depends on client syntax and proxy settings
Header Footprint May append proxy headers if misconfigured Operates at the transport session layer without inserting HTTP headers
Selenium Syntax --proxy-server=http://HOST:PORT --proxy-server=socks5://HOST:PORT

SOCKS5 forwards connections at the proxy layer and generally does not add HTTP headers. However, DNS behavior, UDP support, and application compatibility depend on the client and proxy implementation. Review the current residential proxy protocols documentation before selecting a scheme.

The Core Challenge: Selenium & Proxy Authentication

A common obstacle when setting up a proxy in Selenium is authentication. If your proxy provider issues credentials in the standard URI format http://username:password@proxy.example.com:8080, passing this directly to ChromeOptions will fail:

# THIS DOES NOT WORK IN CHROMIUM
options.add_argument("--proxy-server=http://user:password@proxy.example.com:8080")

Chromium’s command-line parser strips embedded credentials for security reasons. When the browser attempts to connect to a protected endpoint, it triggers an OS-level HTTP basic authentication dialog box. Because this alert exists outside the browser DOM, standard Selenium WebDriver commands (driver.switch_to.alert) cannot interact with it, causing automated scripts to hang.

To resolve this, developers use two primary integration patterns:

  1. IP Whitelisting (Recommended for Simplicity): Register your client or runner machine public IP in your proxy provider dashboard. The proxy gateway accepts connections without credential challenges.
  2. Dynamic Chrome Extension (For Dynamic Client IPs): Package a lightweight extension at runtime to intercept chrome.webRequest.onAuthRequired events and supply credentials automatically.

The examples below target the following software baseline. They are provided as reproducible patterns; run them in your own authorized environment and record the actual versions and proxy response before production use:

Component Recommended Baseline Notes
Python Python 3.9+ / 3.10+ Standard CPython runtime
Selenium selenium>=4.10.0 Modern WebDriver API
Browser Google Chrome / Chromium 114+ Check the target browser’s headless and extension policies
ChromeDriver Matching Chrome major version Managed natively or via webdriver-manager
Target OS Linux, macOS, Windows Cross-platform compatibility

Install required Python dependencies:

python -m pip install "selenium>=4.10.0"

Execution status: NOT EXECUTED in the publication environment. The proxy endpoint, credentials, browser version, operating system, and provider account configuration must be supplied before either example can produce a valid live result.

Method 1: Native ChromeOptions Setup (IP Whitelisted)

When your client IP is authorized in your provider dashboard, configuring Selenium requires passing the proxy argument directly to ChromeOptions. This method avoids browser extensions. Review the Selenium proxy integration and the provider’s current browser requirements before running it.

Before running your script, export your proxy endpoint into an environment variable:

export PROXY_SERVER="http://HOST:PORT"
import os
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

# Retrieve proxy endpoint strictly from environment variable
proxy_endpoint = os.environ["PROXY_SERVER"]

options = webdriver.ChromeOptions()
options.add_argument(f"--proxy-server={proxy_endpoint}")
options.add_argument("--headless=new")
options.add_argument("--disable-gpu")
options.add_argument("--no-sandbox")

driver = webdriver.Chrome(options=options)

try:
    # Verify egress IP against an authorized IP reflection service
    driver.get("https://api.ipify.org?format=json")
    WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.TAG_NAME, "body"))
    )
    print("Observed Response:", driver.find_element(By.TAG_NAME, "body").text)
finally:
    driver.quit()

Consult the documentation for proxy whitelisted IPs before using this pattern. Replace HOST:PORT with the endpoint and port assigned to your authorized account; the example does not assert a universal Socks5.IO endpoint.

Method 2: Handling Proxy Authentication with a Chrome Extension

When automating from dynamic IP environments where whitelisting is impractical, you can construct a temporary Chrome extension for supported HTTP/HTTPS proxy authentication flows. SOCKS5 authentication behavior depends on the browser, proxy implementation, and provider configuration; verify it against the official provider documentation before using it in production.

To prevent syntax errors and script injection risks, all credentials and host parameters must be safely JSON-encoded before injecting them into the extension background script.

import os
import json
import zipfile
import tempfile
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

def create_proxy_auth_extension(proxy_host, proxy_port, proxy_user, proxy_pass, proxy_scheme="http"):
    """
    Constructs a temporary Chrome extension zip to authenticate against
    HTTP or HTTPS proxy authentication flows.
    """
    # Validate and normalize proxy scheme
    valid_schemes = {"http", "https"}
    if proxy_scheme.lower() not in valid_schemes:
        raise ValueError(f"Unsupported proxy scheme: {proxy_scheme}. Choose from http or https")

    manifest_json = {
        "version": "1.0.0",
        "manifest_version": 2,
        "name": "Selenium Proxy Auth Helper",
        "permissions": [
            "proxy",
            "tabs",
            "unlimitedStorage",
            "storage",
            "<all_urls>",
            "webRequest",
            "webRequestBlocking"
        ],
        "background": {
            "scripts": ["background.js"]
        },
        "minimum_chrome_version": "22.0.0"
    }

    # Safely serialize configuration and credentials to prevent injection
    config_data = {
        "mode": "fixed_servers",
        "rules": {
            "singleProxy": {
                "scheme": proxy_scheme.lower(),
                "host": str(proxy_host),
                "port": int(proxy_port)
            },
            "bypassList": ["localhost", "127.0.0.1"]
        }
    }

    auth_data = {
        "username": str(proxy_user),
        "password": str(proxy_pass)
    }

    background_js = f"""
    var config = {json.dumps(config_data)};
    chrome.proxy.settings.set({{value: config, scope: "regular"}}, function() {{}});

    function callbackFn(details) {{
        return {{
            authCredentials: {json.dumps(auth_data)}
        }};
    }}

    chrome.webRequest.onAuthRequired.addListener(
        callbackFn,
        {{urls: ["<all_urls>"]}},
        ['blocking']
    );
    """

    temp_zip = tempfile.NamedTemporaryFile(suffix=".zip", delete=False)
    temp_zip_path = temp_zip.name
    temp_zip.close()

    with zipfile.ZipFile(temp_zip_path, "w") as zp:
        zp.writestr("manifest.json", json.dumps(manifest_json, indent=2))
        zp.writestr("background.js", background_js)
    
    return temp_zip_path

if __name__ == "__main__":
    # Load credentials strictly from environment variables
    proxy_host = os.environ["PROXY_HOST"]
    proxy_port = os.environ["PROXY_PORT"]
    proxy_user = os.environ["PROXY_USER"]
    proxy_pass = os.environ["PROXY_PASS"]
    proxy_scheme = os.environ.get("PROXY_SCHEME", "http")

    plugin_path = create_proxy_auth_extension(
        proxy_host, proxy_port, proxy_user, proxy_pass, proxy_scheme
    )

    options = webdriver.ChromeOptions()
    options.add_extension(plugin_path)
    options.add_argument("--headless=new")

    driver = webdriver.Chrome(options=options)

    try:
        driver.get("https://api.ipify.org?format=json")
        WebDriverWait(driver, 10).until(
            EC.presence_of_element_located((By.TAG_NAME, "body"))
        )
        print("Observed Authenticated IP:", driver.find_element(By.TAG_NAME, "body").text)
    finally:
        driver.quit()
        if os.path.exists(plugin_path):
            os.remove(plugin_path)

Note on Extension Compatibility: This example targets supported HTTP/HTTPS authentication flows only. Manifest V2 availability is subject to Chrome version policies and enterprise settings, and extension loading behavior should be verified against the target Chrome and Selenium versions. For production pipelines, prefer the proxy provider’s current documented authentication method or IP whitelisting where feasible.

Client-Side Browser Restarts vs. Gateway-Level IP Rotation

When automating multi-page crawls or regression tests, developers often ask: How do I set up a rotating proxy in Selenium with Python?

Two core architectural models exist:

selenium-rotating-proxy-workflow

The Inefficient Model: Client-Side Driver Restarts

Some automation pipelines attempt IP rotation by terminating and relaunching WebDriver for each task with a new --proxy-server flag. This introduces operational drawbacks:

  • Process Overhead: Re-launching browser instances consumes considerable CPU and memory resources.
  • Latency Penalty: Initializing browser binaries on every request adds significant execution time.
  • Resource Exhaustion: Rapid process spawning increases the risk of orphaned chromedriver processes and port exhaustion.

The Scalable Model: Upstream Gateway Proxy Rotation

With gateway-level rotation, your Selenium script connects to a single persistent proxy endpoint (for example, HOST:PORT). The upstream proxy service manages IP pool assignment according to the selected product and session settings:

  • Per-Request or Session Rotation: A supported gateway may assign a different residential IP per connection or retain an IP for a configured session duration. Confirm the behavior in the provider’s current residential proxy session control documentation.
  • Resource Preservation: A single WebDriver instance processes multiple requests sequentially without browser restarts.
  • Simplified Client Code: Network rotation logic is decoupled from browser automation logic.

selenium-proxy-auth-methods

Selecting Socks5.IO Proxy Infrastructure for Selenium

Matching your Selenium automation requirements to the appropriate proxy network tier ensures predictable performance and session stability:

  • Distributed Data Verification & Market Audits: Evaluate dynamic residential proxies when the current product configuration matches a workflow that needs rotating residential exits across selected regions. Confirm current locations, protocols, and session behavior on the product page before deployment.
  • Cellular Network & Mobile Experience Testing: Evaluate Socks5.IO mobile proxies when the current product configuration provides the required mobile-network exit for an authorized test. Confirm the current network, location, protocol, and session details on the official product page before relying on the route.
  • Stateful Navigation & Extended Workflows: Evaluate Socks5.IO static residential proxies when a workflow requires a stable residential or ISP endpoint. Confirm current address allocation, protocol support, and session terms on the official product page before deployment.

Review the official product pages to verify current region availability, session duration controls, and protocol specifications before deploying production automation jobs.

Executable Python Verification Script

Here is an end-to-end Python template configured for Selenium with SOCKS5 or HTTP proxy routing, headless execution, and explicit wait verification against an authorized echo endpoint.

selenium-socks5-integration-code

import os
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

def init_selenium_proxy_driver():
    # Retrieve proxy URL strictly from environment variable
    # Expected formats: http://HOST:PORT or socks5://HOST:PORT
    proxy_server = os.environ["PROXY_SERVER"]
    
    options = webdriver.ChromeOptions()
    options.add_argument(f"--proxy-server={proxy_server}")
    
    # Modern headless configuration
    options.add_argument("--headless=new")
    options.add_argument("--disable-gpu")
    options.add_argument("--disable-dev-shm-usage")
    options.add_argument("--no-sandbox")
    options.add_argument("--window-size=1920,1080")
    
    driver = webdriver.Chrome(options=options)
    return driver

if __name__ == "__main__":
    driver = init_selenium_proxy_driver()
    try:
        print("[INFO] Navigating to authorized IP verification endpoint...")
        driver.get("https://api.ipify.org?format=json")
        
        # Explicit wait for page body rendering
        WebDriverWait(driver, 10).until(
            EC.presence_of_element_located((By.TAG_NAME, "body"))
        )
        
        ip_output = driver.find_element(By.TAG_NAME, "body").text
        print(f"[SUCCESS] Proxy Connected! Observed Public IP: {ip_output}")
        
    except Exception as e:
        print(f"[ERROR] Proxy verification failed: {e}")
    finally:
        driver.quit()
        print("[INFO] WebDriver closed cleanly.")

Note on SOCKS5 helper scripts: While Chromium handles SOCKS5 proxy URLs natively via --proxy-server=socks5://HOST:PORT, standalone Python validation scripts utilizing the requests library require SOCKS support. Install it via python -m pip install "requests[socks]" before running non-Selenium network tests.

Selenium Proxy Troubleshooting Matrix

When setting up proxy servers in automated browsers, network or configuration mismatches can interrupt execution. Use this matrix to diagnose and resolve common failure modes:

Symptom Likely Cause How to Verify Smallest Useful Fix
ERR_PROXY_CONNECTION_FAILED Proxy gateway is offline, port is closed, or host address is mistyped Test endpoint connectivity with curl -x PROXY_URL https://api.ipify.org Check endpoint hostname, port, and network firewall rules
ERR_TUNNEL_CONNECTION_FAILED Upstream proxy failed TLS handshake or rejected CONNECT request Inspect target protocol and proxy server access logs Verify destination port permissions and retry with backoff
OS Authentication Popup Freezes Script Chromium received HTTP 407 without an extension or IP whitelist Inspect browser window or headless timeout logs Configure IP whitelisting in dashboard or load the auth extension
Egress IP Does Not Rotate Script connects to a static port rather than a rotating gateway endpoint Query api.ipify.org across several sequential requests Update endpoint configuration to the provider’s rotating gateway
High Memory / Zombie Processes Browser instances spawned in loops without clean driver.quit() Check system process monitor for orphaned chromedriver binaries Wrap driver lifecycle in try...finally blocks

Final Recommendation & Best Practices

selenium-proxy-decision-framework

  1. Leverage Upstream Gateway Rotation: For large-scale data validation, route traffic through a dynamic residential proxy gateway rather than managing client-side browser pools.
  2. Prioritize IP Whitelisting: Simplify deployment and avoid extension dependencies by authorizing automation server IPs in your provider dashboard.
  3. Implement Explicit Waits and Retries: Network routing over residential and mobile proxy pools experiences variable latency. Always wrap page navigations in WebDriverWait with retry logic.
  4. Adhere to Responsible Automation Practices: Respect target site terms of service, observe robots.txt directives, enforce reasonable request rates, and never store plaintext credentials in version control.

FAQs

Pass the SOCKS5 proxy URL directly to ChromeOptions using --proxy-server=socks5://HOST:PORT. For authenticated SOCKS5 connections, use the provider's documented authentication method or IP whitelist. The HTTP/HTTPS extension example in this guide should not be assumed to handle SOCKS5 authentication. Test the route against an authorized IP endpoint, then confirm DNS, session, and protocol behavior in the same client environment.