Pydoll speaks the Chrome DevTools Protocol directly, so there is no WebDriver binary and no navigator.webdriver flag. It clicks and types like a person and injects a consistent fingerprint, so the anti-bot that stops ordinary scrapers waves it through.
pip install pydoll-python* clearing Cloudflare also depends on IP reputation and a matched profile
Sites profile three layers: what your browser says it is, how it behaves, and how it answers a challenge. Pydoll gives you a real answer for each, switchable exactly where you need it.
User-Agent, navigator, WebGL, screen, timezone and locale, aligned into one identity that survives toString and reaches Web Workers.
await tab.apply_fingerprint(profile)
Center-clicks and 50ms keystrokes are a fingerprint. Pydoll curves the cursor along a Bezier path and types with a human rhythm.
await el.click(humanize=True)
When a protected page throws the Turnstile checkbox, Pydoll detects and clicks it. Honest caveat: clearing it still leans on your IP.
async with tab.expect_and_bypass_cloudflare_captcha():
Selenium-style tools drive Chrome through a WebDriver binary that announces itself. Pydoll removes that layer and builds the stealth in.
| Pydoll | Selenium / WebDriver tools | |
|---|---|---|
| navigator.webdriver | false | true |
| Driver binary | none | required, version-matched |
| Fingerprint injection | built in | manual or none |
| Humanized input | built in | none |
| Transport | CDP over WebSocket | WebDriver HTTP |
| Concurrency | native asyncio | sync + threads |
| Setup | pip install | driver download + PATH |
No drivers, no PATH, no version-matching. A full async session in a dozen lines.
import asyncio from pydoll.browser import Chrome from pydoll.constants import Key async def main(): async with Chrome() as browser: tab = await browser.start() await tab.go_to('https://google.com') box = await tab.find(name='q') await box.type_text('Pydoll', humanize=True) await tab.keyboard.press(Key.ENTER) asyncio.run(main())
search.py does, liveEverything you reach for on a real scraping job, in one typed, async-native library.
Their support keeps the project maintained and growing, and every deal below is exclusive to Pydoll users.
The #1 newsletter dedicated to web scraping. Read their full, independent review of Pydoll.
read the review →High-quality proxies for scraping and automation. ZIP targeting, 99.9% uptime, no KYC.
PYDOLL3535% offPYDOLL4040% off ISPRotating residential proxies: 10TB at $0.35/GB or 1TB at $0.50/GB for Pydoll users.
PAY210% off rechargeThe next milestone unlocks Firefox support, a big step that opens a whole new range for the library. Momentum is the incentive that makes a feature that large worth taking on.
navigator.webdriver to true and needs version-matching to your browser. Pydoll connects straight to Chrome over the DevTools Protocol, removing that layer, that flag, and the whole class of driver-mismatch errors, while giving direct access to events, network interception and JS execution in the real tab.navigator.webdriver: false and shows no automation flags. With apply_fingerprint() and humanize=True it scores zero detections across CreepJS, SannySoft, BrowserScan and BrowserLeaks. Honest caveat: clearing challenges like Cloudflare Turnstile also depends on your IP reputation and on the profile matching your host OS and Chrome version. Pydoll gives you the tools, not a magic bypass.apply_fingerprint() overrides User-Agent, Client Hints, navigator, WebGL, screen, fonts, timezone and locale as one coherent identity. The point is consistency: a single overridden signal that contradicts the others is a stronger giveaway than an untouched browser, so Pydoll changes them together.await browser.new_tab() and run them together with asyncio.gather. Each tab keeps its own session and state, giving true parallel automation without threads.Pydoll is MIT licensed. Read the source, ship with it, contribute, or sponsor a maintainer doing this mostly solo.