Skip to content

ProxyHatCom/selenium-proxyhat

Repository files navigation

selenium-proxyhat

Route Selenium Chrome through ProxyHat residential proxies — authenticated gateway proxies that just work in vanilla Selenium, plus a sticky residential IP pinned for the whole session, geo-targeting, and rotation.

CI Compatible with selenium latest PyPI License: MIT

Tip

Recommended proxies — ProxyHat residential IPs. Every feature in this package is tested end-to-end against ProxyHat and works great. First-class integration; also works with any proxy, or none.

Why

Chrome's --proxy-server flag can't carry a username and password, so pointing Selenium at a credentialed residential gateway normally means an ugly page.authenticate / CDP dance or an extra proxy dependency. And running a real browser from a datacenter IP gets flagged, CAPTCHA-walled, and blocked anyway.

selenium-proxyhat fixes both. It plugs ProxyHat's residential IPs (50M+ across 148+ countries) into Selenium and handles gateway auth by auto-generating a tiny in-memory Chrome extension that answers the proxy's auth challenge — works with vanilla Selenium, no selenium-wire required. One pinned residential IP per session by default, so cookies and fingerprint stay consistent while your script works.

Install

pip install selenium-proxyhat

selenium>=4.10 and proxyhat come with it. Bring your own Chrome + chromedriver (Selenium Manager resolves the driver for you).

Quick start

from selenium_proxyhat import proxyhat_driver

# An API key (PROXYHAT_API_KEY) auto-selects an active residential sub-user:
driver = proxyhat_driver(country="us")   # sticky US IP for the whole session
driver.get("https://httpbin.org/ip")
print(driver.find_element("tag name", "body").text)
driver.quit()

Get an API key at proxyhat.com.

Prefer to build the driver yourself? Get configured ChromeOptions (proxy flag + auth extension already applied) and launch Chrome your way:

from selenium import webdriver
from selenium_proxyhat import proxyhat_chrome_options

options = proxyhat_chrome_options(country="de", sticky="1h")
options.add_argument("--headless=new")   # add whatever else you need
driver = webdriver.Chrome(options=options)

Credentials

Pass them explicitly or via environment variables — options win over env:

Option Env var Notes
api_key PROXYHAT_API_KEY Auto-selects an active sub-user with remaining traffic
sub_user PROXYHAT_SUBUSER Pick a specific sub-user by uuid or name (with an API key)
username PROXYHAT_USERNAME Explicit gateway proxy_username (skips the API)
password PROXYHAT_PASSWORD Explicit gateway proxy_password

Targeting

proxyhat_chrome_options(
    country="us",      # ISO code or "any" (default)
    region="california",
    city="new_york",
    filter="high",     # AI IP-quality tier
    sticky="30m",      # session lifetime (default); sticky=False rotates every request
)

Same keyword arguments work on proxyhat_driver(...) and proxyhat_seleniumwire_options(...).

Sticky IP per session (default)

A browser session takes many steps against the same site — logging in, clicking, scrolling. If the exit IP changed mid-session the site would see a user teleporting between cities and block it. So this package is sticky by default: one residential IP is pinned for the whole session (sticky="30m", renewed as you work), keeping cookies and fingerprint coherent.

Want a fresh IP on every request instead (e.g. many independent one-shot fetches)? Turn stickiness off:

proxyhat_chrome_options(country="us", sticky=False)  # rotating residential IP per connection

Set a custom lifetime with sticky="2h".

How authentication works

Chrome takes the proxy host/port from --proxy-server=gate.proxyhat.com:8080, but a residential gateway needs a username (the ProxyHat targeting string) and password. Since the flag can't carry them, proxyhat_chrome_options generates a minimal Manifest V3 extension in memory whose background service worker answers chrome.webRequest.onAuthRequired with your credentials, and adds it via ChromeOptions.add_extension. The MV3 blocking auth listener is enabled by the webRequestAuthProvider permission. Nothing is written to your project — the packed extension lives in a temp file that Chrome reads at launch.

The targeting username (e.g. <user>-country-us-sid-<id>-ttl-30m) is built by the official proxyhat SDK, so a sticky session mints a single session id shared across the run.

selenium-wire alternative (optional)

Already using selenium-wire? Skip the extension and let selenium-wire carry credentials in the upstream-proxy URL:

from seleniumwire import webdriver           # pip install selenium-proxyhat[seleniumwire]
from selenium_proxyhat import proxyhat_seleniumwire_options

driver = webdriver.Chrome(
    seleniumwire_options=proxyhat_seleniumwire_options(country="us"),
)
# -> {"proxy": {"http": "http://<user>:<pass>@gate.proxyhat.com:8080", "https": ..., "no_proxy": ...}}

selenium-wire is an optional extra; proxyhat_seleniumwire_options() only builds the dict and never imports it. It also supports protocol="socks5" for an authenticated SOCKS5 upstream (which the extension path does not).

License

MIT © ProxyHat

About

Route Selenium through ProxyHat residential proxies — authenticated proxy via a generated extension, geo-targeting, sticky sessions.

Topics

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors

Languages