10% off ALL new Proxies – CODE: 10pro

nodriver Proxy Setup: Route Chrome via German Mobile IPs

nodriver Proxy Setup: Route Chrome via German Mobile IPs

The One Thing Most nodriver Proxy Guides Get Wrong

nodriver — the successor to undetected-chromedriver, driving Chromium directly over the DevTools Protocol — gives you a clean browser_args list to set a proxy. What trips people up is the username and password: Chromium does not read credentials from the --proxy-server value, so the http://USER:PASS@HOST:PORT you'd use with requests silently drops the USER:PASS part, and your first navigation fails with 407 Proxy Authentication Required.

There is no page.authenticate in nodriver. The credentials go in over the CDP Fetch domain instead:

  1. Pass only the host and port in browser args: --proxy-server=PROXY_HOST:PORT.
  2. Enable the Fetch domain with handle_auth_requests=True, then answer the auth challenge with your username and password via continue_with_auth.

nodriver is a library for making an automated browser present a consistent, realistic fingerprint so you can reach public data reliably — not a tool for defeating access controls. The other half of that reliability is the egress IP: a real German mobile IP with solid IP reputation is what a well-behaved crawler needs on German platforms.


Before You Start

You need four values from your GermanProxy.io account:

  • Host and port of your endpoint
  • Username and password

The examples use PROXY_HOST, PORT, USER and PASS as placeholders — replace them with your own. Install nodriver (Python 3.9+):

pip install nodriver

Step 1 — Start Chromium Through the Proxy (host and port)

If your endpoint uses IP-allowlist authentication, this is the whole setup — the host and port go in browser_args:

import asyncio
import nodriver as uc

PROXY_HOST = "PROXY_HOST"
PORT = "PORT"


async def main():
    browser = await uc.start(
        browser_args=[f"--proxy-server={PROXY_HOST}:{PORT}"],
    )
    page = await browser.get("https://www.example.de")
    print("Title:", await page.evaluate("document.title"))
    browser.stop()


asyncio.run(main())

For a credential-based endpoint, add the auth handler in the next step before your first navigation.


Step 2 — Handle Username/Password Auth over CDP Fetch

Chromium raises an auth challenge for a credential proxy. Register the Fetch handlers, enable the domain with handle_auth_requests=True, and answer the challenge with continue_with_auth:

import asyncio
import nodriver as uc
from nodriver import cdp

PROXY_HOST = "PROXY_HOST"
PORT = "PORT"
USER = "USER"
PASS = "PASS"


async def main():
    browser = await uc.start(
        browser_args=[f"--proxy-server={PROXY_HOST}:{PORT}"],
    )
    tab = browser.main_tab

    async def on_auth(event: cdp.fetch.AuthRequired):
        # Reply with the credentials for the proxy's auth challenge.
        asyncio.create_task(
            tab.send(
                cdp.fetch.continue_with_auth(
                    request_id=event.request_id,
                    auth_challenge_response=cdp.fetch.AuthChallengeResponse(
                        response="ProvideCredentials",
                        username=USER,
                        password=PASS,
                    ),
                )
            )
        )

    async def on_paused(event: cdp.fetch.RequestPaused):
        # Non-auth pauses: just let the request continue unchanged.
        asyncio.create_task(
            tab.send(cdp.fetch.continue_request(request_id=event.request_id))
        )

    # Add handlers first, then enable the Fetch domain with auth handling.
    tab.add_handler(cdp.fetch.AuthRequired, on_auth)
    tab.add_handler(cdp.fetch.RequestPaused, on_paused)
    await tab.send(cdp.fetch.enable(handle_auth_requests=True))

    page = await browser.get("https://www.example.de")
    print("Title:", await page.evaluate("document.title"))
    browser.stop()


asyncio.run(main())

Two details matter: add the handlers before you enable the Fetch domain, and reply from inside the handler with asyncio.create_task(...) (fire-and-forget) so one paused request doesn't block the others. AuthChallengeResponse carries response="ProvideCredentials" plus your username and password.


Step 3 — Verify the IP Before You Scale

Confirm you're actually on a German mobile IP before you build anything on top of it. Point the browser at an IP-echo endpoint and read the result:

page = await browser.get("https://api.ipify.org?format=json")
ip = await page.evaluate("document.body.innerText")
print("Egress IP:", ip)

If it returns your own address, re-check that the host and port are in --proxy-server and that the Fetch handlers were added before the first navigation. For a fuller checklist, see verifying your mobile proxy. A persistent 407 points at the credentials — see how to fix 407 proxy authentication required.


Step 4 — Check for WebRTC and DNS Leaks

A proxy routes Chromium's HTTP traffic, but the browser has two side channels that can expose your real address:

  • WebRTC can surface your local IP via ICE candidates even with a proxy set — see what a WebRTC leak is.
  • DNS can resolve names outside the tunnel depending on configuration — see what a DNS leak is.

For data-collection work in headless mode WebRTC is usually inert, but verify it for any flow where IP consistency matters. A real German mobile IP only helps if nothing else leaks past it — walk through both with how to check a proxy for leaks.


HTTP vs. SOCKS5 in nodriver

Both protocols come with your endpoint. Which to pass in --proxy-server depends on what you need:

Aspect HTTP endpoint SOCKS5 endpoint
Browser arg --proxy-server=HOST:PORT --proxy-server=socks5://HOST:PORT
Username/password auth in Chromium Yes, via the CDP Fetch handler No — Chromium has no SOCKS5 user/pass auth
Best auth mode Credentials IP allowlist
Typical use Default for most scraping Lower-level / non-HTTP traffic

For most nodriver scraping, the HTTP endpoint with the Fetch auth handler is the simplest path. Reach for SOCKS5 when you specifically need it and can use IP-allowlist authentication. Background: SOCKS5 vs HTTP proxy.


Sticky Sessions vs. Rotation

With a dedicated German endpoint you control the IP at the proxy, not in your code:

  • Sticky session: keep one browser open across a multi-step flow — login, navigate, paginate — and the German mobile IP stays the same.
  • Rotation on demand: when you want a fresh IP, trigger rotation at the proxy and start a new browser. There's no per-request IP pool to manage in nodriver.

This is why a dedicated endpoint keeps the code small: no rotation list, no health-checking, no retry-on-dead-IP loop. See sticky sessions and IP rotation explained and dedicated vs shared mobile proxy.


Why a Mobile IP for nodriver at All

nodriver is a common choice for JavaScript-heavy pages that a plain HTTP client can't render — product pages, SERPs, dashboards. The catch is the egress IP: datacenter ranges are widely distrusted, so even a perfectly behaved crawler can hit friction. A real German mobile IP rides on carrier-grade NAT (CGNAT), the same shared-IP space thousands of ordinary phone users sit behind, which is why it carries higher IP reputation on German platforms — the point that matters more than any browser-side setting, since websites also detect proxies by the IP itself.

For the trade-offs against other IP types, see mobile vs residential vs datacenter proxy and what is a mobile proxy.


Scrape Responsibly

A mobile proxy improves reliability for legitimate data collection — it is not a tool to circumvent access controls or platform rules. Keep your nodriver crawl clean and defensible:

  1. Respect each site's terms and its robots.txt; collect only public data you're permitted to use.
  2. Throttle with realistic delays between navigations so you don't overload servers — a full Chromium is heavier than a plain HTTP client.
  3. Collect only what you need, and handle any personal data in line with the GDPR. See is web scraping legal in the EU.
  4. Be honest about who you are — don't impersonate a service or misuse a target's security mechanisms.

Whether mobile proxies themselves are lawful to use: are mobile proxies legal.


FAQ

How do I set a proxy in nodriver?

Pass the host and port as a Chromium browser argument when you start: uc.start(browser_args=['--proxy-server=PROXY_HOST:PORT']). For an authenticated proxy you must also handle the credentials over the CDP Fetch domain — Chromium ignores any user:pass embedded in the --proxy-server value.

How does nodriver handle username and password proxy auth?

nodriver has no page.authenticate helper. You enable the CDP Fetch domain with handle_auth_requests=True, add a handler for cdp.fetch.AuthRequired, and reply with cdp.fetch.continue_with_auth carrying an AuthChallengeResponse that holds your username and password. A second handler resumes normal requests with continue_request.

Why does nodriver ignore the credentials in my proxy URL?

Because Chromium — the browser nodriver drives — does not read a username and password from the --proxy-server flag. Passing http://USER:PASS@HOST:PORT silently drops the credentials and your first navigation fails with 407 Proxy Authentication Required. Supply the credentials through the CDP Fetch auth handler instead — see how to fix 407 proxy authentication required.

Can nodriver use a SOCKS5 mobile proxy?

Yes, via browser_args=['--proxy-server=socks5://PROXY_HOST:PORT']. Chromium cannot do SOCKS5 username/password auth, so a SOCKS5 endpoint works best with IP-allowlist authentication. For credential auth, use the HTTP endpoint with the CDP Fetch handler. See the proxy protocol choice.

How do I rotate IPs with nodriver?

With a dedicated German endpoint you rotate on demand at the proxy, not per request in code. For a sticky session, keep one browser open across the flow; to get a fresh IP, trigger rotation at the proxy and start a new browser. See sticky sessions and IP rotation explained.

Is nodriver the successor to undetected-chromedriver?

Yes. nodriver is from the same author and drives Chromium directly over the DevTools Protocol without Selenium or a webdriver binary. Both are libraries for presenting a consistent, realistic browser to reach public data — the proxy work differs because nodriver uses CDP, not selenium-wire. Compare the undetected-chromedriver setup.


Related guides

CTA

Drive nodriver on real German mobile IPs. Get a German mobile proxy — HTTP/SOCKS5/OpenVPN, sticky sessions, on-demand rotation, fair-use 20 GB/day, from a transparent EU provider.


Get a German mobile proxy: Real 4G/5G IPs from Germany, fair-use 20 GB/day — compare German mobile proxy plans or get a dedicated proxy on the Blue network.

Telegram Support
Nach oben scrollen