$ show ultrafunkamsterdam/nodriver
nodriver is an asynchronous Python library for browser automation that communicates directly with Chrome/Chromium via the Chrome DevTools Protocol (CDP), bypassing Selenium and WebDriver. It provides a high-level API (Browser, Tab, Element) for navigating pages, finding and interacting with DOM elements, managing cookies, proxies, and taking screenshots, with built-in anti-detection measures to evade bot blockers like Cloudflare. The codebase includes auto-generated low-level bindings for all CDP domains, a custom async WebSocket connection manager, a dict wrapper with attribute access (ContraDict), and a sofisticated async TCP proxy forwarder for authenticated proxies. The library is alpha-stage but actively maintained, though some CDP domain messagers are depreicated and the generated code requires periodic regeneration to stay in sync with Chrome updates.
The LLM identified 3 files worth highlighting for reuse:
ContraDict is a dictionary subclass that provides attribute-style access to keys, recursive conversion of nested dicts and iterables, and automatic snake_case conversion. It is fully self-contained (imports only typing) and demonstrates a clean, reusable pattern for wrapping JSON-like data in an object-with-attributes interface. Could be extracted verbatim into any Python project needing dict-with-dot access.
The ProxyForwarder class inside util.py implements an async TCP forwarder that handles HTTP CONNECT and SOCKS5 proxy authentication by inserting credentials into the initial handshake. It is self-contained (depends only on asyncio, socket, base64) and solves the common scraping need of using authenticated upstream proxies. The implementation is robust, with proper error handling and support for both IPv4 and IPv6. It can be extracted and reused in any async network project requiring proxy tunneling.
This module defines the `event_class` decorator and `parse_json_event` function used to convert raw CDP event JSON into typed dataclass instances. The pattern is a clean way to bind JSON to Python objects using a mapping of event methods to classes. It is small, self-contained, and demonstrates a reusable pattern for event deserialization in any protocol-driven library. The `event_class` decorator is generic and could be applied to other JSON-based event systems.