{"id":1618,"date":"2026-10-10T22:07:46","date_gmt":"2026-10-10T14:07:46","guid":{"rendered":"\/blog\/?p=1618"},"modified":"2026-10-06T16:14:11","modified_gmt":"2026-10-06T08:14:11","slug":"selenium-proxy-settings","status":"publish","type":"post","link":"\/blog\/selenium-proxy-settings","title":{"rendered":"Selenium Proxy Settings in Python: Manual Setup, Exit-IP Checks, and Auth Limits"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\"><strong>Selenium Proxy Settings<\/strong> in Python require more than simply passing a proxy address to WebDriver. A stable setup should verify the proxy path outside the browser first, configure the manual proxy correctly in Chrome or another WebDriver session, confirm the exit IP, and only then debug the target page. This order matters because browser automation failures, SSL prompts, authentication issues, and selector bugs can easily be confused with proxy failures.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This guide uses Python, Selenium&#8217;s documented proxy capability, and a small exit-IP preflight so you can tell whether the network path is correct before the first browser navigation.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What Selenium can and cannot solve directly<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Selenium can set the browser&#8217;s proxy configuration through WebDriver options. That is the right layer for browser traffic. What Selenium does not standardize is every provider-specific authentication workflow. If your provider issues a browser-compatible endpoint and credentials, use that exact format. If your browser session still triggers a proxy-auth dialog, solve that credential path first rather than trying to patch around it with brittle browser UI automation.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Install the libraries<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>python -m pip install selenium requests<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Keep proxy credentials in environment variables:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>export PROXY_USERNAME=\"YOUR_USERNAME\"\nexport PROXY_PASSWORD=\"YOUR_PASSWORD\"\nexport PROXY_HOST=\"GATEWAY_HOST\"\nexport PROXY_PORT=\"PORT\"<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Step 1: verify the proxy path before launching Chrome<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This preflight uses <code>requests<\/code> with explicit timeouts, credential encoding, and <code>raise_for_status()<\/code>. It tells you whether the authenticated gateway works before Selenium adds browser complexity on top.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import os\nfrom urllib.parse import quote\n\nimport requests\n\n\ndef required(name: str) -&gt; str:\n    value = os.environ.get(name)\n    if not value:\n        raise RuntimeError(f\"Missing environment variable: {name}\")\n    return value\n\n\nuser = quote(required(\"PROXY_USERNAME\"), safe=\"\")\npassword = quote(required(\"PROXY_PASSWORD\"), safe=\"\")\nhost = required(\"PROXY_HOST\")\nport = required(\"PROXY_PORT\")\n\nproxy_url = f\"http:\/\/{user}:{password}@{host}:{port}\"\nproxies = {\"http\": proxy_url, \"https\": proxy_url}\n\nresponse = requests.get(\n    \"https:\/\/httpbin.org\/ip\",\n    proxies=proxies,\n    timeout=(10, 30),\n)\nresponse.raise_for_status()\nprint(response.text)<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If this step fails, stop there. Rechecking credentials, gateway host, and port is faster than trying to debug a browser session that never had a valid proxy path.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 2: pass a manual<a href=\"https:\/\/colaproxy.com\/dynamic-residential-proxies\" target=\"_blank\" rel=\"noopener\"> proxy<\/a> into Selenium<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Selenium&#8217;s options documentation exposes a manual proxy capability. In Python, the easiest path is to build a <code>Proxy<\/code> object, attach it to the browser options, and then launch the driver.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>from selenium import webdriver\nfrom selenium.webdriver.common.by import By\nfrom selenium.webdriver.common.proxy import Proxy, ProxyType\n\n\nproxy = Proxy()\nproxy.proxy_type = ProxyType.MANUAL\nproxy.http_proxy = \"GATEWAY_HOST:PORT\"\nproxy.ssl_proxy = \"GATEWAY_HOST:PORT\"\n\noptions = webdriver.ChromeOptions()\noptions.proxy = proxy\noptions.add_argument(\"--headless=new\")\noptions.add_argument(\"--window-size=1440,900\")\n\ndriver = webdriver.Chrome(options=options)\n\ntry:\n    driver.get(\"https:\/\/httpbin.org\/ip\")\n    print(driver.find_element(By.TAG_NAME, \"body\").text)\n\n    driver.get(\"https:\/\/example.com\")\n    print(driver.title)\nfinally:\n    driver.quit()<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The example intentionally keeps the browser-side proxy value as <code>host:port<\/code>. Do not invent an authenticated URL format for Selenium if your provider documents a different browser path. Copy the browser-compatible endpoint from the dashboard you are actually using.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Why do the preflight and browser step separately?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Because they answer different questions:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The <code>requests<\/code> preflight proves whether the authenticated proxy credentials and network path work.<\/li>\n\n\n\n<li>The Selenium run proves whether the browser traffic is using the expected proxy route.<\/li>\n\n\n\n<li>Together they tell you whether a failure belongs to the gateway, the browser setup, or the target page.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">This split is especially useful when a target page loads slowly or shows an interstitial. Without the preflight, teams often change WebDriver settings when the real issue is a wrong proxy endpoint or a page-level challenge.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Common failures and what they actually mean<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Failure<\/th><th>Likely layer<\/th><th>Fastest next check<\/th><\/tr><\/thead><tbody><tr><td><code>407 Proxy Authentication Required<\/code> in the preflight<\/td><td>Credential or endpoint issue<\/td><td>Recopy the credentials and confirm they belong to the intended proxy product.<\/td><\/tr><tr><td>Browser opens but the IP does not change<\/td><td>Browser proxy setting did not apply<\/td><td>Check <code>http_proxy<\/code> and <code>ssl_proxy<\/code>, then reload the IP-check page in Selenium.<\/td><\/tr><tr><td>HTTPS pages fail but HTTP pages work<\/td><td>Only the HTTP proxy was set<\/td><td>Set both <code>http_proxy<\/code> and <code>ssl_proxy<\/code>.<\/td><\/tr><tr><td>The target page times out<\/td><td>Could be the proxy path or the target site<\/td><td>Retest the IP-check endpoint inside Selenium first, then the target page.<\/td><\/tr><tr><td>Unexpected certificate or auth prompt<\/td><td>Browser-specific proxy auth path is incomplete<\/td><td>Use the exact provider-supported browser endpoint; do not script around prompts until the network path is documented.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Selenium Proxy Settings for Production Browser Jobs<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Keep the exit-IP check at session startup, not on every page, unless the workflow is explicitly testing rotation.<\/li>\n\n\n\n<li>Log status codes, page titles, and driver version, but never log raw proxy passwords.<\/li>\n\n\n\n<li>Use responsible rate limits and only automate pages you are authorized to access.<\/li>\n\n\n\n<li>If a proxy issue appears only in Selenium and not in the preflight, review the browser endpoint format before changing the target-site logic.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Where<a href=\"\/blog\/infrastructure-web-scraping-automation-2026\" data-type=\"post\" data-id=\"1677\"> ColaProxy<\/a> fits<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">ColaProxy&#8217;s public site states support for HTTP(S) and SOCKS5 protocols plus multiple proxy product types. That makes it a reasonable fit for browser validation workflows, but the exact browser endpoint syntax and any region or session controls should always come from the current dashboard rather than from a copied blog snippet.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If your workflow is not browser-heavy, the <a href=\"\/blog\/python-proxy-health-checker\">Python proxy health checker<\/a> is a faster way to validate gateways. If you are comparing browser stacks instead of fixing Selenium specifically, the <a href=\"\/blog\/playwright-proxy-authentication\">Playwright proxy authentication guide<\/a> shows the equivalent setup in Playwright.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Next step<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Get the preflight stable first, then launch one headless browser, confirm the exit IP, and only after that add the real target flow or parallel workers.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A practical Selenium proxy workflow for Python: preflight the authenticated gateway with Requests, set a manual browser proxy, and verify the exit IP before real automation.<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[3],"class_list":["post-1618","post","type-post","status-publish","format-standard","hentry","category-proxy","tag-proxy"],"_links":{"self":[{"href":"\/blog\/wp-json\/wp\/v2\/posts\/1618","targetHints":{"allow":["GET"]}}],"collection":[{"href":"\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"\/blog\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"\/blog\/wp-json\/wp\/v2\/comments?post=1618"}],"version-history":[{"count":1,"href":"\/blog\/wp-json\/wp\/v2\/posts\/1618\/revisions"}],"predecessor-version":[{"id":2038,"href":"\/blog\/wp-json\/wp\/v2\/posts\/1618\/revisions\/2038"}],"wp:attachment":[{"href":"\/blog\/wp-json\/wp\/v2\/media?parent=1618"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"\/blog\/wp-json\/wp\/v2\/categories?post=1618"},{"taxonomy":"post_tag","embeddable":true,"href":"\/blog\/wp-json\/wp\/v2\/tags?post=1618"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}