Selenium with Mobile Proxies: Chrome and Firefox
Selenium drives a real browser from code. It is the standard tool when a site needs JavaScript to render, when you must click through a flow, or when you are testing your own web application against real browser behaviour. The catch for data collection and QA work is that a browser launched from a server carries a server IP, and many sites treat that differently from a phone. Mobile proxies close that gap. At WeProx we run real SIM cards in 4G and 5G modems on AT&T, T-Mobile and Verizon, with unlimited data, so Selenium sessions can browse on a genuine US carrier IP for as long as the job takes. This guide covers how to pass an authenticated proxy to Chrome and Firefox drivers, how to give each driver its own proxy, and how to rotate between sessions without restarting your whole pipeline.
What Selenium needs from a proxy
Selenium itself does not talk to the proxy; the browser does. So the question is how each browser accepts proxy settings. Chrome takes a proxy server flag at launch, in the form of a scheme, host and port. Firefox takes proxy preferences in its profile, with separate fields for host, port and type. Both browsers support HTTP and SOCKS5 proxies.
The wrinkle is authentication. Chrome's launch flag has no place for a username and password, so an authenticated proxy triggers a login prompt that Selenium cannot dismiss. The reliable approaches are a small extension that answers the proxy authentication challenge, a local forwarder that adds the credentials and exposes an unauthenticated port on localhost, or, on newer Selenium releases, the BiDi-based network interception that can supply credentials. Firefox has similar options.
A WeProx proxy gives you a host, an HTTP port, a SOCKS5 port, a username and password, and a rotation link. Those are the inputs for every method described here.
Authenticated proxies in ChromeDriver
The simplest robust method is a tiny Chrome extension that sets the proxy and answers the authentication challenge. It consists of a manifest with proxy and webRequest permissions and a background script that calls the proxy settings API with your host and port, then registers an onAuthRequired listener returning your username and password. Zip those two files and pass the zip to ChromeOptions with the add_extension method. When Chrome starts, it is already routed through your WeProx proxy and never shows a prompt.
If you would rather not ship an extension, run a local forwarder. Tools such as a small HTTP proxy relay accept connections on localhost, attach your credentials, and forward to the WeProx host and port. Then launch Chrome with the proxy-server argument pointing at the local port. This method also works in headless mode and in containers where extensions are awkward.
The Selenium project's BiDi support offers a third path: enable BiDi in ChromeOptions, add a network authentication handler that supplies the credentials, and launch with the plain proxy-server argument.
- Extension method: manifest plus background script, zipped and added with add_extension.
- Forwarder method: local relay with credentials, Chrome pointed at localhost.
- BiDi method: network auth handler in recent Selenium releases.
- Any method works with the HTTP port; the forwarder method also works for SOCKS5.
Authenticated proxies in Firefox with GeckoDriver
Firefox reads proxy configuration from preferences. In FirefoxOptions, set the preference for proxy type to manual, then set the HTTP host and port, the SSL host and port, and optionally the SOCKS host, port and version. Add the preference that routes DNS through SOCKS if you use SOCKS5, so name lookups happen on the proxy side.
For credentials, Firefox will show an authentication dialog unless handled. The practical options are the same local forwarder approach, which keeps the browser configuration free of secrets, or a Firefox add-on that answers the proxy challenge. Many teams standardise on the forwarder so both Chrome and Firefox drivers use the same pattern.
One proxy per driver and rotation between sessions
For anything beyond a single script, give each WebDriver instance its own WeProx proxy. Build a small function that takes a proxy record, host, port, username and password, produces the options object for the browser, and returns a driver. Then keep a list of proxy records and map them onto workers. Each worker runs one browser on one carrier IP, which keeps sessions independent and makes failures easy to attribute.
Rotation fits naturally at the boundary between sessions. When a driver quits, call the rotation link for its proxy with a plain HTTP request, wait for the new IP to be active, and start the next driver. The host, port and credentials never change, so the driver factory does not need to know a rotation happened. WeProx rotations are unlimited on every plan with no wait between changes, so you can rotate on every session if your workload wants fresh addresses.
For browsing that must stay on one IP, keep the session sticky and do not call the link until the work is done. Per-request rotation is available as a proxy mode too, but in a browser it tends to break logged-in flows, so reserve it for stateless page fetches.
Scaling and grouping by city
When your collection or test plan spans regions, assign proxies by metro. WeProx modems are located in New York, Los Angeles, Chicago, Houston, Phoenix, Miami, North Carolina and Boston, with Boston on 4G LTE only. A worker pool tagged by city lets you verify that a price, an ad or a page layout is what a mobile visitor in that city actually sees.
Location moves are free and self-service from your dashboard, so if a pool needs more Phoenix capacity next week you can repoint proxies without a ticket. Because WeProx includes unlimited data, long-running crawls that render full pages in a browser do not need a data budget.
Troubleshooting
A hanging browser at startup with no page loaded is usually the authentication prompt waiting for input. Confirm the extension or forwarder is actually in place, and that the port matches the protocol.
If pages load but a geolocation check shows the wrong region, the browser may be using a cached location or a manually set timezone. Clear the profile between sessions and let the site derive location from the proxy IP.
Leaks of your server IP come from WebRTC or from DNS resolved locally. Disable WebRTC through a preference or extension, and use proxy-side DNS with SOCKS5 or stay on the HTTP port, where the hostname goes to the proxy.
Sessions that lose login state mid-run are almost always a rotation link being called while a driver is alive. Move the call to after driver.quit and the problem disappears.
Why WeProx carrier IPs for Selenium
Selenium gives you a real browser; the proxy decides what kind of visitor that browser appears to be. Our IPs come from real SIMs in modems we own and operate on AT&T, T-Mobile and Verizon. Carrier NAT means the address is shared with ordinary phone users, which is why sites serve the same content to a Selenium session on WeProx as they do to a handset.
Our 4G proxies typically deliver 20 to 45 Mbps and 5G delivers 50+ Mbps, comfortably enough for full page renders. Each proxy includes HTTP(S) and SOCKS5 with UDP, sticky or per-request modes, a rotation link, an API, and unlimited data. Plans start from $4/day, with daily, weekly and monthly terms, so a single test driver can start today.
Frequently asked
Why does Chrome show a proxy login popup that Selenium cannot close?
Chrome's proxy-server flag has no field for credentials, so an authenticated proxy triggers a dialog. Use a small extension that answers the authentication challenge, a local forwarder that adds credentials, or Selenium's BiDi network authentication where available.
Can each Selenium driver use a different WeProx proxy?
Yes. Build a driver factory that takes a proxy record and produces the browser options for it, then start one driver per proxy. Each driver runs on its own carrier IP.
How do I rotate the IP between Selenium sessions?
After the driver quits, send a plain HTTP request to the proxy's rotation link, then start the next driver. Host, port and credentials stay the same. Rotations are unlimited with no wait between changes.
Should I use HTTP or SOCKS5 with Selenium?
HTTP is the easiest for page loads and works with all the authentication methods above. SOCKS5 is useful when you want DNS resolved on the proxy side or need UDP, and it works well with the local forwarder pattern.