nodriver vs Patchright: Undetected Browser Automation in Python
Advanced Bot Mitigation Engineer
TL;DR:
- nodriver and Patchright are driver-level undetected automation tools — they hide the signals that mark a session as automated, rather than shipping a new browser engine the way Obscura or Lightpanda do.
- nodriver is the successor to undetected-chromedriver: an async Python framework that talks Chrome DevTools Protocol directly, with no Selenium and no
chromedriverbinary, so the classic webdriver tells are gone by design. It is AGPL-3.0 and past 4,000 GitHub stars. - Patchright is a drop-in replacement for Playwright Python that patches the leaks Playwright's own automation surface exposes — same API,
from patchright.sync_api import sync_playwright, Apache-2.0 licensed. - Both report
navigator.webdriverasfalseout of the box — verified live below on each — which is the first flag most bot detectors read. - Neither supplies IPs or solves challenge pages. Driver-level stealth hides automation; it does nothing for IP reputation or a traffic-validation wall. Scrapeless Scraping Browser adds residential proxies in 195+ countries and challenge handling to the same session.
- Free to start. New Scrapeless accounts include free Scraping Browser runtime — sign up at app.scrapeless.com.
Introduction: two ways to look undetected, one thing they don't do
Anti-bot systems catch automation in two broad places: the browser (fingerprint surfaces like WebGL and fonts) and the driver (the machinery that controls the browser — the navigator.webdriver property from the W3C WebDriver spec, Chrome DevTools Protocol artifacts, the automation control the standard tools expose). Engine-level tools like a patched Firefox rework the first. nodriver and Patchright attack the second: they keep a normal Chromium but strip the giveaways that a normal automation stack leaves behind.
They come at it from opposite directions. nodriver throws out Selenium entirely and drives Chrome over the DevTools Protocol from async Python. Patchright keeps Playwright exactly as-is and patches the leaks underneath it, so existing Playwright code runs unchanged. This guide installs both, runs the same task through each, shows the shared limitation neither solves, and explains how a managed cloud browser fills that gap.
What these tools are — and what "driver-level" means
Driver-level stealth is about how the browser is controlled, not what the browser is. A standard Selenium or Playwright session leaks its nature through control-channel artifacts: the navigator.webdriver property set to true, CDP runtime hooks, an automation extension. Detectors look for exactly these. nodriver and Patchright remove them while leaving you on ordinary Chromium.
nodriver is the maintained successor to the widely used undetected-chromedriver. It is an async-first Python framework that speaks CDP directly — no chromedriver executable, no Selenium webdriver layer, so there is no webdriver binary to fingerprint in the first place. Its own description frames it as a fast framework for automation and scraping that gets past systems like Cloudflare and hCaptcha, and it is licensed AGPL-3.0.
Patchright takes the compatibility route: it is an undetected re-implementation of the Playwright Python package that patches the detection leaks in Playwright's automation surface. You install it in place of Playwright and change one import; everything else — selectors, contexts, evaluate — is the Playwright you already write. It is Apache-2.0, a more permissive license than nodriver's copyleft, which can matter when you embed it in a commercial product.
Install both
nodriver installs from PyPI and brings its own Chrome handling; Patchright installs like Playwright and downloads a Chromium build:
bash
# nodriver — async CDP framework, successor to undetected-chromedriver
pip install nodriver
# Patchright — drop-in undetected Playwright, plus its Chromium build
pip install patchright
patchright install chromium
nodriver: async CDP, no webdriver layer
nodriver's API is async and CDP-native. This launches Chrome, navigates, and reads back the automation flag:
python
import nodriver as uc
async def main():
browser = await uc.start(headless=True)
page = await browser.get("https://example.com")
await page.sleep(1)
print("TITLE:", await page.evaluate("document.title"))
print("WEBDRIVER:", await page.evaluate("navigator.webdriver"))
browser.stop()
# nodriver ships its own loop helper so teardown stays clean
uc.loop().run_until_complete(main())
This prints TITLE: Example Domain and WEBDRIVER: False. There is no chromedriver process and no Selenium in the stack — the control channel is raw CDP, so the webdriver signal is absent rather than patched over. Using uc.loop() instead of a bare asyncio.run keeps nodriver's own event-loop teardown clean.
Patchright: the same Playwright, minus the leaks
If you already have Playwright code, Patchright is a one-line switch — the import changes and nothing else does:
python
# The only change from Playwright: import from patchright, not playwright
from patchright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
page = browser.new_page()
page.goto("https://example.com")
print("TITLE:", page.title())
print("WEBDRIVER:", page.evaluate("navigator.webdriver"))
browser.close()
This also prints WEBDRIVER: False. Because the API is identical to Playwright's, an existing Playwright scraper adopts Patchright's stealth by swapping the import — no rewrite, no new mental model.
Get your API key on the free plan: app.scrapeless.com
Which one — and the gap both leave open
Choosing between them comes down to your starting point. If you are writing fresh async Python and want the leanest CDP-direct path with no Selenium legacy, nodriver fits — note its AGPL-3.0 copyleft before embedding it commercially. If you have Playwright code or a team fluent in the Playwright API, Patchright gives you the same surface with the leaks patched and a permissive Apache-2.0 license. Both keep you on ordinary Chromium; neither asks you to learn a new engine.
The gap they share is the important part. Driver-level stealth hides that a session is automated. It does not change where the session comes from, and it does not answer a challenge page. Three failure modes sit entirely outside what these tools address:
- IP reputation. Your requests leave from your machine's IP. A target that blocks datacenter ranges or rate-limits your address blocks a spotless webdriver-free session exactly as fast as a naive one.
- Challenge pages. A traffic-validation interstitial still has to be solved. Looking un-automated lowers how often one appears; it does not clear the ones that do.
- Fingerprint depth. These tools focus on the control channel, not the full engine-level fingerprint surface a dedicated anti-detect browser rewrites.
All three are network-and-infrastructure problems, and no driver-level library solves them because they are not driver-level problems.
Where Scrapeless Scraping Browser fits
When the target gates on IP reputation or serves challenges — not just on the webdriver flag — the missing pieces are residential egress and challenge handling. Scrapeless Scraping Browser delivers both in one managed session: an anti-detection cloud browser powered by self-developed Chromium, with residential proxies in 195+ countries selected per session, exposed as a CDP endpoint. Because Patchright is Playwright, connecting to it is the same connect_over_cdp call Playwright already uses:
python
import os
from playwright.sync_api import sync_playwright
# Cloud Chromium with residential egress — the IP + challenge tier
API_KEY = os.environ["SCRAPELESS_API_KEY"]
ws_endpoint = (
"wss://browser.scrapeless.com/api/v2/browser"
f"?token={API_KEY}&session_ttl=180&proxy_country=US"
)
with sync_playwright() as p:
browser = p.chromium.connect_over_cdp(ws_endpoint)
page = browser.contexts[0].new_page() if browser.contexts else browser.new_page()
page.goto("https://example.com", wait_until="domcontentloaded")
print("TITLE:", page.title())
browser.close()
The practical pattern is a tiered one: nodriver or Patchright for self-hosted runs against targets that only check the driver, and a Scrapeless session for the targets that also weigh IP and issue challenges. The Scrapeless documentation has the full parameter reference, and pricing is usage-based with a free tier. For the challenge-page half specifically, the walkthrough on solving Cloudflare with Python shows the managed session clearing what a driver-only stack can't.
Conclusion: hide the driver, then solve the network
nodriver and Patchright are the two strongest driver-level answers to automation detection — nodriver by discarding Selenium for direct CDP, Patchright by patching Playwright in place — and both clear the webdriver flag every detector checks first. Pick by your codebase and license needs, and be clear about the boundary: they hide automation, not infrastructure.
For targets that also judge IP reputation and throw challenges, keep a Scrapeless Scraping Browser session in the rotation. Everything here speaks CDP or Playwright, so routing a request from a self-hosted stealth run to a managed cloud session is a connection-string change, not a rewrite.
Ready to Build Your AI-Powered Data Pipeline?
Join our community to claim a free plan and connect with developers building undetected automation pipelines: Discord · Telegram.
Sign up at app.scrapeless.com for free Scraping Browser runtime and route your IP-and-challenge targets through it while nodriver or Patchright handle the driver-only ones.
FAQ
Q: What is the difference between nodriver and Patchright?
nodriver is an async framework that drives Chrome directly over CDP with no Selenium or chromedriver, and is the successor to undetected-chromedriver. Patchright is a drop-in replacement for the Playwright Python package that patches Playwright's detection leaks while keeping the exact Playwright API. Choose nodriver for a fresh CDP-native stack, Patchright to add stealth to existing Playwright code.
Q: Do nodriver and Patchright hide navigator.webdriver?
Yes — both report navigator.webdriver as false by default, verified live in this guide. nodriver removes the webdriver signal by not using a webdriver layer at all; Patchright patches it out of Playwright's surface.
Q: Are these anti-detect browsers like Camoufox?
No. Camoufox is an engine-level anti-detect browser that rewrites fingerprint surfaces inside Firefox. nodriver and Patchright are driver-level: they run ordinary Chromium and hide the automation control channel. The two approaches address different detection layers and can be complementary.
Q: Which license should I check before using them commercially?
nodriver is AGPL-3.0 (copyleft, with network-use obligations); Patchright is Apache-2.0 (permissive). If license terms constrain your product, Patchright is the more permissive of the two — but review both against your own requirements.
Q: Why add Scrapeless if my session already looks un-automated?
Because looking un-automated only defeats driver-level checks. Hard targets also weigh IP reputation and serve challenge pages, and no driver-level library moves your IP or solves a challenge. Scrapeless Scraping Browser bundles residential proxies in 195+ countries and challenge handling into one managed CDP session, covering the layer these tools do not.
At Scrapeless, we only access publicly available data while strictly complying with applicable laws, regulations, and website privacy policies. The content in this blog is for demonstration purposes only and does not involve any illegal or infringing activities. We make no guarantees and disclaim all liability for the use of information from this blog or third-party links. Before engaging in any scraping activities, consult your legal advisor and review the target website's terms of service or obtain the necessary permissions.



