Setup guide
Selenium proxy authentication in Python
Chrome rejects a --proxy-server value that carries a username and password, which is where most older Selenium answers stall. Selenium 4.32 added a network module that answers the proxy’s login over WebDriver BiDi, so the archived selenium-wire package and home-made extensions are no longer needed. Both Chrome and Firefox are covered, from Python.
Before you start
- Python 3 and Selenium 4.32 or newer. Selenium Manager ships inside the package and fetches a matching driver on the first run.
- Chrome or Firefox installed on the machine that runs the script.
- HOST, PORT, USERNAME and PASSWORD copied from your service page.
Your connection details
Sign in to the dashboard and open the service you bought. Its page shows the host, port, username and password for that service. There is no single ProxyPanda address to remember, so copy them from there each time. The code in these guides uses the placeholders below; replace each one with your own value.
- HOST
- The proxy address for this service, exactly as the service page shows it.
- PORT
- The port to connect to. Copy it with the host, since it can differ from one service to the next.
- USERNAME
- Your proxy login. It is separate from the email you use for the dashboard.
- PASSWORD
- Copy it in full. On residential, the options you choose in the dashboard are added to the end of the password, so a password typed from memory loses them.
You can skip the username and password by adding the IP address you connect from to the service’s allowlist. Then only HOST and PORT go into your code.
The examples use HTTP, which reaches https sites through an encrypted tunnel. SOCKS5 works too: residential ports accept both, and ISP and datacenter proxies switch protocol in the dashboard.
Steps
Install or upgrade Selenium
The network and browsing_context helpers used below arrived in 4.32. Older releases fail at the import line, so confirm the version number before anything else.
terminal pip install -U selenium python -c "import selenium; print(selenium.__version__)"Put the address in the flag and the login in add_auth_handler
enable_bidi opens a WebDriver BiDi channel next to the classic one. The --proxy-server flag carries the scheme, host and port and nothing more. driver.network.add_auth_handler then waits for the proxy’s 407 and replies with your credentials, in every tab of the session.
check_ip.py from selenium import webdriver from selenium.webdriver.common.bidi.browsing_context import ReadinessState options = webdriver.ChromeOptions() options.enable_bidi = True options.add_argument("--proxy-server=http://HOST:PORT") driver = webdriver.Chrome(options=options) driver.network.add_auth_handler("USERNAME", "PASSWORD") driver.browsing_context.navigate( context=driver.current_window_handle, url="https://api.ipify.org", wait=ReadinessState.COMPLETE, ) print(driver.find_element("tag name", "body").text) driver.quit()Load the first page with browsing_context.navigate
In Chrome, a classic driver.get holds the driver while the page loads, and the login reply needs that same driver, so the two wait on each other until the script times out. Navigating over BiDi sidesteps the deadlock. Once the proxy has accepted the login, Chrome keeps using it, and plain driver.get calls work for the rest of the session.
Run the same check in Firefox
Firefox takes the proxy through Selenium’s Proxy object, with one entry for plain HTTP and one for HTTPS. Its BiDi support answers the login during an ordinary driver.get, so this version needs no special navigation.
check_ip_firefox.py from selenium import webdriver from selenium.webdriver.common.proxy import Proxy options = webdriver.FirefoxOptions() options.enable_bidi = True options.proxy = Proxy({"httpProxy": "HOST:PORT", "sslProxy": "HOST:PORT"}) driver = webdriver.Firefox(options=options) driver.network.add_auth_handler("USERNAME", "PASSWORD") driver.get("https://api.ipify.org") print(driver.find_element("tag name", "body").text) driver.quit()Go headless on a server
Before creating the driver, add options.add_argument("--headless=new") for Chrome or options.add_argument("-headless") for Firefox. Nothing else changes: the handler replies to the proxy with or without a window.
Rotating and sticky IPs
One Selenium session opens many connections: the page, its scripts, its images. On residential with Randomize IP, those can leave from different addresses, and a site may see a single visit arrive from several places. Choose Sticky IP when the script signs in or fills a form across pages.
To start over as someone new, quit the driver and create a fresh one. Its cookies go with it, and on Randomize IP the next session starts from another address.
An ISP or datacenter IP does not change during its rental term, so every session you open through it presents the same address.
Common errors and fixes
net::ERR_NO_SUPPORTED_PROXIES
The --proxy-server flag has USERNAME:PASSWORD in it, a form Chrome refuses. Leave http://HOST:PORT in the flag and hand the login to add_auth_handler.
net::ERR_INVALID_AUTH_CREDENTIALS
Chrome met the proxy’s 407 and nothing answered it. Make sure add_auth_handler runs before the first navigation.
Unable to find url to connect to from capabilities
options.enable_bidi = True is missing, so there is no BiDi channel for driver.network to use. Set it on the options before the driver is created.
net::ERR_TOO_MANY_RETRIES
The handler sent a login and the proxy kept refusing it. The username or password is wrong or cut short; copy both again from the service page.
Timed out waiting for response to BiDi command, then ReadTimeoutError
Chrome opened its first page with driver.get and the login reply got stuck behind it. Use browsing_context.navigate for that first page, as in step 3.
ModuleNotFoundError: No module named 'selenium.webdriver.common.bidi.browsing_context'
The installed Selenium predates 4.32. Upgrade it with pip install -U selenium.
Which line to pick
Selenium drives a full browser, so every image and script counts as traffic. Datacenter IPs keep test runs and dashboard checks cheap when the site accepts server addresses. Reach for residential with Sticky IP where the site inspects the network, and ISP for a profile that returns to the same account day after day.
Other setup guides
Not sure what a word means? The glossary explains it in plain English.
Stuck on a step?
Paste the command and the error into Discord, with your password taken out. People there have met most of these errors before.