Skip to main content

Truedriver ✌️

License Pypi Version Issues Pull Requests codecov [Downloads()] 💬 Discord · ⚠️ Report Bug · 💡 Request Feature

This package is a fork of cdpdriver/zendriver, which itself is a fork of ultrafunkamsterdam/nodriver, created to add new features, compile unmerged bugfixes, and increase community engagement.

Truedriver is a blazing fast, async-first, undetectable webscraping/web automation framework implemented using the Chrome Devtools Protocol. Visit websites, scrape content, and run JavaScript using a real browser (no Selenium/Webdriver) all with just a few lines of Python.

Docker support is here! Check out cdpdriver/truedriver-docker for an example of how to run Truedriver with a real, GPU-accelerated browser (not headless) in a Docker container. (Linux-only)

Features

  • Undetectable - Truedriver uses the Chrome Devtools Protocol instead of Selenium/WebDriver, making it (almost) impossible to detect
  • Blazing fast - Chrome Devtools Protocol is fast, much faster than previous Selenium/WebDriver solutions. CDP combined with an async Python API makes Truedriver highly performant.
  • Feature complete and easy to use - Packed with allowing you to get up and running in just a few lines of code.
  • First-class Docker support - Traditionally, browser automation has been incredibly difficult to package with Docker, especially if you want to run real, GPU-accelerated Chrome (not headless). Now, deploying with Docker is easier than ever using the officially supported truedriver-docker project template.
  • Automatic cookie and profile management - By default, uses fresh profile on each run, cleaning up on exit. Or, save and load cookies to a file to avoid repeating tedious login steps.
  • Smart element lookup - Find elements selector or text, including iframe content. This could also be used as wait condition for a element to appear, since it will retry for the duration of timeout until found. Single element lookup by text using tab.find() accepts a best_match flag, which will not naively return the first match, but will match candidates by closest matching text length.
  • Full iframe support - Switch between iframe contexts to interact with embedded content like hCaptcha, forms, or any other iframe-based widgets. Supports finding frames by URL, name, element, or index.
  • Simple proxy support - Easy proxy configuration with multiple formats including authenticated proxies. Works reliably with Chrome, Brave, and Edge using URL-based authentication (like Playwright).
  • Easy debugging - Descriptive repr for elements, which represents the element as HTML, makes debugging much easier.

Installation

To install, simply use pip (or your favorite package manager):

pip install truedriver
# or uv add truedriver, poetry add truedriver, etc.

Usage

Basic Example

Example for visiting https://www.browserscan.net/bot-detection and saving a screenshot of the results:

import asyncio

import truedriver as td


async def main():
    browser = await td.start()
    page = await browser.get("https://www.browserscan.net/bot-detection")
    await page.save_screenshot("browserscan.png")
    await browser.stop()


if __name__ == "__main__":
    asyncio.run(main())

Iframe Interaction

Interact with embedded content like hCaptcha, forms, or widgets:

import asyncio
import truedriver as td

async def main():
    browser = await td.start()
    tab = await browser.get("https://example.com/page-with-iframe")

    # Find iframe by URL pattern
    hcaptcha_frame = await tab.find_frame_by_url(r".*hcaptcha\.com.*")
    if hcaptcha_frame:
        # Switch to the iframe
        await tab.switch_to_frame(hcaptcha_frame)

        # Now interact with elements inside the iframe
        checkbox = await tab.find("#checkbox")
        await checkbox.click()

        # Switch back to main frame
        await tab.switch_to_main_frame()

    await browser.stop()

if __name__ == "__main__":
    asyncio.run(main())

Proxy Support

Truedriver supports proxies in multiple formats, including authenticated proxies. Just pass the proxy argument to td.start():

Supported formats:

  • Simple: "ip:port" or "http://ip:port"
  • Authenticated (string): "username:password@ip:port" or "http://username:password@ip:port"
  • Authenticated (dict): { "server": "ip:port", "username": "user", "password": "pass" }

Example:

import asyncio
import truedriver as td

async def main():
    # Simple proxy
    browser = await td.start(proxy="proxy.example.com:8080")


    # Authenticated proxy (string format)
    browser = await td.start(proxy="your-username:your-password@proxy.example.com:8080")

    # Authenticated proxy (dict format)
    proxy_config = {
        "server": "proxy.example.com:8080",
        "username": "your-username",
        "password": "your-password"
    }
    browser = await td.start(proxy=proxy_config)


    tab = await browser.get("https://httpbin.org/ip")
    print(await tab.get_content())
    await browser.stop()

if __name__ == "__main__":
    asyncio.run(main())

Note: Replace your-username, your-password, and proxy.example.com:8080 with your actual proxy credentials. Truedriver automatically handles proxy authentication using the Chrome DevTools Protocol—no manual CDP handlers required.

Advanced Configuration

Example with multiple features:

import asyncio
import truedriver as td

async def main():
    # Start browser with proxy and custom user agent
    browser = await td.start(
        headless=False,
        proxy="user:pass@proxy.example.com:8080",
        user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
        browser_args=[
            "--disable-blink-features=AutomationControlled",
            "--disable-web-security"
        ]
    )

    tab = await browser.get("https://example.com")

    # Work with iframes if needed
    frames = await tab.get_frames()
    print(f"Found {len(frames)} frames")

    # Find and interact with elements
    element = await tab.find("Click me")
    await element.click()

    await browser.stop()

if __name__ == "__main__":
    asyncio.run(main())

Check out the Quickstart for more information and examples.

What's New in Truedriver

Truedriver enhances the original zendriver with powerful new features for advanced web automation:

🎯 Full Iframe Support

  • Switch between iframe contexts with ease using tab.switch_to_frame()
  • Find frames by URL, name, or element using tab.find_frame_by_url(), tab.find_frame_by_name()
  • Frame-aware operations - all element finding and JavaScript execution works within the current frame
  • Perfect for hCaptcha, forms, and embedded widgets

🌐 Simple Proxy Support

  • Multiple configuration formats:
    • Simple: "ip:port"
    • Authenticated: "user:pass@ip:port"
    • Dict: {"server": "ip:port", "username": "user", "password": "pass"}
  • URL-based authentication (like Playwright) - no complex CDP auth handlers
  • Works reliably with Chrome, Brave, and Edge

🥷 Enhanced Stealth

  • Advanced anti-detection techniques for bypassing sophisticated bot detection
  • Improved fingerprint randomization and user agent handling
  • Optimized browser arguments for maximum undetectability
  • Better evasion of modern anti-bot solutions

📦 Easy Migration from zendriver

All zendriver code works with truedriver - just change your import:

# Old
import zendriver as td

# New
import truedriver as td

🚀 Real-World Examples

  • Discord account creation with proxy rotation and iframe handling
  • hCaptcha solving using iframe switching
  • Complex form automation across multiple frames
  • Stealth scraping with enhanced undetection

Rationale for the fork

Truedriver remains committed to zendriver's goals of staying undetected for all modern anti-bot solutions and also keeps with the batteries-included approach of its predecessor. This project is a specialized fork of zendriver which itself was forked from the original nodriver repo.

Truedriver aims to provide enhanced stealth capabilities by:

  1. Implementing advanced anti-detection techniques
  2. Fine-tuning browser arguments for maximum stealth
  3. Maintaining compatibility with zendriver's API while focusing on undetectability
  4. Providing specialized builds for bypassing sophisticated bot detection systems

Credits

  • Original nodriver by ultrafunkamsterdam
  • zendriver by cdpdriver team
  • Truedriver enhancements and stealth improvements by the current maintainer

With these enhancements, we hope to further the development of state-of-the-art open-source web automation tools, helping to make the web truly accessible for automation purposes.

Contributing

Contributions of all types are always welcome! Please see CONTRIBUTING.md for details on how to contribute.

Getting additional help

If you have a question, bug report, or want to make a general inquiry about the project, please create a new GitHub issue. If you are having a problem with Truedriver, please make sure to include your operating system, Chrome version, code example demonstrating the issue, and any other information that may be relevant.

Questions directed to any personal accounts outside of GitHub will be ignored.

Metadata

Release files for truedriver 0.1.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for truedriver 0.1.5
File Size Uploaded Provenance
truedriver-0.1.5.tar.gz 389.3 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for truedriver 0.1.5
File Interpreter ABI Platform
truedriver-0.1.5-py3-none-any.whl Python 3 none any Details

Total release size: 749.9 kB

Release files / truedriver-0.1.5.tar.gz

Download URL truedriver-0.1.5.tar.gz
Size 389.3 kB
Tags Source
SHA-256 checksum
How to use checksums
697106f826db3e701cc196241fe856a91c2ab16073cd2e8f1962577e67ef0375
BLAKE2b-256 checksum
How to use checksums
de625f170ea64149ba732af0cbce039d36b46c8b4c5e9b3b79e606c8f3ad5102
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.6

Release files / truedriver-0.1.5-py3-none-any.whl

Download URL truedriver-0.1.5-py3-none-any.whl
Size 360.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
525d79d2abed7cd6313c62276f4f62557fa6c1682f8f4997d73e97173435bdd6
BLAKE2b-256 checksum
How to use checksums
f7160ff15049a2332da862b36d9f0f2994069fa36d68ffe711c58f918fc10311
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.6

Security for truedriver 0.1.5

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page