Selenium Proxy Setup with Python: Capabilities, Auth, and Testing

Configure Selenium 4 with the official WebDriver proxy capability, understand authenticated-proxy limits, verify the browser exit, isolate sessions, and diagnose failures.

Written by the Mexela Editorial Team. Technical guides are reviewed by the Mexela Technical Team under the Mexela Editorial Policy.

Python Selenium browser session routed through a red proxy gateway toward a test web server

Key topics:

PROXY PLANS

Ready to buy proxies for this workflow?

Use the guide below to choose the right proxy type, then start with private proxies for dedicated IPv4 access or shared proxies when price matters more.

To use a proxy with Selenium 4 in Python, create a manual WebDriver Proxy, set its HTTP and SSL gateway to HOST:PORT, attach it to the browser options, and launch the driver. Verify the observed exit from inside that browser before running the real test. The standard WebDriver proxy capability carries routing fields, not a portable username/password field, so plan proxy authentication separately instead of hiding credentials inside an unsupported capability.

Scope: this guide covers current Selenium 4 Python bindings and a single HTTP proxy route for a browser session. It does not promise that every browser driver handles proxy authentication, DNS, PAC files, or SOCKS exactly the same way. Compare non-browser clients in the cURL, Python Requests, and Node.js guide, browse the Proxy Setup and Developer Guides hub, or use the Puppeteer proxy tutorial when the project is already based on Node.js and Chromium.

Start with a controlled Selenium environment

Create a fresh virtual environment, install Selenium from the approved package source, and let Selenium Manager resolve a compatible driver when that fits the environment. Record the Python, Selenium, browser, and driver versions before diagnosing network behavior. A version mismatch can fail before the proxy is ever used.

# macOS or Linux
python3 -m venv .venv
. .venv/bin/activate
python -m pip install selenium
python -c "import selenium; print(selenium.__version__)"

# Windows PowerShell
py -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install selenium
python -c "import selenium; print(selenium.__version__)"

If pip itself needs an outbound proxy, configure that installation layer with the pip proxy guide. Do not confuse the proxy used to download Selenium with the proxy the automated browser will use later.

Configure the official WebDriver proxy capability

Selenium’s current driver documentation demonstrates the Python Proxy object and browser options. The WebDriver proxy capability supports named fields such as httpProxy, sslProxy, socksProxy, noProxy, and proxyType. For ordinary HTTPS websites reached through an HTTP forward proxy, set both HTTP and SSL gateway fields to the same assigned HOST:PORT.

from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType

PROXY_HOST = "HOST"
PROXY_PORT = "PORT"

proxy = Proxy()
proxy.proxy_type = ProxyType.MANUAL
proxy.http_proxy = f"{PROXY_HOST}:{PROXY_PORT}"
proxy.ssl_proxy = f"{PROXY_HOST}:{PROXY_PORT}"
proxy.no_proxy = "localhost,127.0.0.1"

options = webdriver.ChromeOptions()
options.proxy = proxy

driver = webdriver.Chrome(options=options)

The endpoint does not include http:// in these capability fields in the common manual form. Keep the proxy object and browser options visible in one setup function so a later test cannot silently launch a direct browser. If the organization uses Firefox, create webdriver.FirefoxOptions() and attach the same standard capability, then verify actual behavior in that driver rather than assuming parity.

Set bounded timeouts and guarantee cleanup

A browser can wait indefinitely enough to make a bad route look like a hung test suite. Set page-load and script timeouts, then close the driver in finally. Keep the first request small and independent of application login state.

from selenium.common.exceptions import WebDriverException

try:
    driver.set_page_load_timeout(30)
    driver.set_script_timeout(15)
    driver.get("https://api.ipify.org?format=json")
    print(driver.find_element("tag name", "body").text)
except WebDriverException as exc:
    print({"error_type": type(exc).__name__})
    raise
finally:
    driver.quit()

Do not print the complete exception if the browser or surrounding code may include a proxy URL containing credentials. Log a sanitized endpoint label, browser version, step name, and error class. The route is easier to diagnose when evidence is consistent and secret-free.

Authentication boundary: routing capability is not a credential API

The W3C-style proxy capability represented by Selenium’s Proxy class does not define portable username and password properties. Embedding USER:PASSWORD@HOST:PORT into http_proxy may be rejected, ignored, or exposed, depending on the browser and driver. Chrome can display a proxy authentication dialog that WebDriver does not handle like a normal page alert.

The most reproducible options are:

  1. Use source-IP allowlisting when the Selenium runner has a stable public egress and the proxy service supports it.
  2. Use an organization-approved local forwarding component that handles upstream credentials outside the browser and exposes a restricted local endpoint to the test.
  3. Use a maintained browser policy or extension owned and reviewed by the team when credentials must be supplied inside the browser process.
  4. Choose a browser automation stack with a documented credential API if the project has not standardized on Selenium.

Do not copy a random extension encoded in a test script or adopt an abandoned interception package solely because it suppresses the prompt. Such code can read all browser traffic and credentials. The proxy authentication guide compares source-IP and username/password models, including the operational consequences of each.

Expected observation: with an allowlisted runner or approved credential bridge, the browser opens the HTTPS exit-check page without a proxy prompt, the body contains a valid public address, and the address differs from the recorded direct baseline when the assigned endpoint differs.

Exit verification inside the same Selenium browser

Verification must happen in the exact session that will run the test. A successful curl command proves curl’s route, not Selenium’s. Capture the page URL, document title, content type when available through browser tooling, and body text before parsing a JSON result.

import json
import ipaddress

driver.get("https://api.ipify.org?format=json")
raw = driver.find_element("tag name", "body").text
data = json.loads(raw)
observed_ip = ipaddress.ip_address(data["ip"])
print({"exit_ip": str(observed_ip)})

Record a direct baseline from the same machine in a separate, intentionally direct browser session. Close that session before launching the proxied one. If the address is unchanged, confirm that the proxy gateway is supposed to use a different public exit and inspect the capability actually passed to the driver.

Do not use a search engine or account page as the first connectivity check. A destination can show consent, CAPTCHA, rate, account, or policy responses even while the proxy works. Establish the route on a neutral endpoint, then perform one approved application action.

Session isolation: one browser, one intended route, one job

Selenium creates a new browser session when the driver starts. Keep cookies, local storage, browser profile, and one intended proxy route together for that session. Do not reuse a personal Chrome profile or a shared profile directory; background tabs, extensions, saved DNS settings, and account state can change both traffic and observations.

For concurrent tests, create a separate driver and temporary profile for each route. Cap concurrency at the aggregate workload approved for the destination. A pool of addresses does not justify multiplying request volume. If a test needs a stable account session, do not rotate the proxy halfway through login or checkout because one request was slow.

Close every driver deterministically. Orphaned browser processes retain memory, file handles, and possibly authenticated proxy state. In a test framework, put teardown in a fixture that runs after both passes and failures.

Bypass local services deliberately

The no_proxy capability can keep loopback and approved internal hosts direct, but browser implementations can differ on syntax. Test the precise hostname used by the application. localhost, 127.0.0.1, and a machine hostname are different strings, and a test server bound to IPv6 loopback adds another case.

Keep the bypass list narrow. A broad domain suffix may send a production-like destination direct and invalidate a regional test. Log whether each test URL is expected to be proxied or bypassed before navigation.

SOCKS and DNS behavior require a separate acceptance test

Selenium exposes SOCKS fields and a SOCKS version in its Python proxy API, but destination DNS behavior depends on the browser, driver, and capability combination. Do not treat an HTTP configuration as proof of SOCKS behavior. For protocol and DNS concepts, read the SOCKS5 setup guide, then build a browser-specific test that distinguishes local gateway resolution from destination resolution.

Browser troubleshooting by symptom

Symptom Likely boundary First check
ERR_PROXY_CONNECTION_FAILED Gateway DNS, route, port, or listener Confirm the assigned host and port once outside the browser
Proxy authentication dialog Credential method not satisfied by the standard capability Confirm IP allowlisting or the approved credential bridge
407 response Proxy reached but authentication rejected Check allowlisted public IP, account state, and credential scope
Certificate warning TLS trust or interception Stop and inspect the chain; never disable validation
Direct IP still visible Capability missing, ignored, or bypassed Inspect session capabilities and bypass rules
Only the application site fails Destination, account, consent, or test behavior Preserve response state and compare the neutral exit check
Driver fails before navigation Browser/driver/runtime compatibility Record versions and reproduce without proxy changes

Use the layered proxy test and common proxy error guide to classify the failing boundary. Repeatedly launching new browsers with different IPs can turn a deterministic configuration problem into noisy destination traffic.

A maintainable Selenium proxy fixture

Keep route configuration in one function that accepts non-secret host and port values, creates options, starts the driver, applies timeouts, and returns the driver only after an exit check passes. Keep the expected exit or endpoint label in test data. Inject secrets through the approved authentication layer, not through assertions or screenshot names.

Separate three tests: route acceptance, application smoke test, and full workflow. If route acceptance fails, skip the application tests with a clear infrastructure reason. If the neutral route passes but the application smoke test fails, preserve that distinction for the application or policy owner.

Responsible-use boundary: automate only systems and accounts you are authorized to test, respect destination terms and rate limits, use official APIs when required, cap retries and concurrency, and redact cookies, tokens, screenshots, and proxy credentials. A browser controlled by Selenium remains accountable traffic.

Choose a route after the Selenium fixture is reproducible

Record the browser family, driver version, country, protocol, authentication model, session duration, parallel browser count, and measured latency. If the approved test requires a stable exclusive exit, compare those requirements with current private proxy options only after the route check, application smoke test, and teardown all work predictably.