Chrome DevTools Protocol automation toolkit — zero-dependency, ~15KB vs 300MB Playwright
Project description
CDP Toolkit
Freelance demos: https://ameobius-space.github.io/kwork-portfolio/
Chrome DevTools Protocol automation without external dependencies. No Playwright, no Selenium, no Puppeteer. Pure Python stdlib.
Install
pip install cdp-toolkit
Why CDP Toolkit?
| Feature | Playwright | Selenium | cdp-toolkit |
|---|---|---|---|
| Dependencies | 50+ packages | 20+ packages | 0 |
| Install size | ~140MB | ~150MB | ~13KB |
| Browser download | Yes (~200MB) | Yes (~100MB) | No |
| Cold start (import) | ~200ms | ~500ms | <1ms |
| Learning curve | Medium | High | Low |
| Speed | Fast | Slow | Fastest |
| Cloud-native | Yes | Partial | Yes |
Metrics: measured via scripts/benchmark.py in CI (artifact: benchmark_results.json). cdp-toolkit: 12.6KB package, 0.34ms import, 0.3KB peak RAM on parameter-builder path. Playwright: 140MB package (pip, no browser binary). Run python scripts/benchmark.py to reproduce.
CDP Toolkit talks directly to Chrome's DevTools Protocol via HTTP and WebSocket. You bring your own Chrome instance (local, Docker, or cloud), and CDP Toolkit handles the rest.
Categories
CDP Toolkit is organized into focused, composable modules:
CDPClient
The core HTTP client for the Chrome DevTools Protocol. It manages tabs (targets), navigates pages, evaluates JavaScript, and captures screenshots, all without requiring Playwright, Selenium, or external browser drivers.
CDPInput
Helpers for text input and form handling. It can generate React/Vue/Angular-compatible native setter JavaScript, dispatch key events, and insert text, making it easy to drive forms in modern JavaScript apps.
CDPMouseEvents
Parameter builders for Input.dispatchMouseEvent. It covers clicks, right-clicks, double-clicks, hovers, pointer moves, and drag-and-drop interactions.
CDPNavigation
Page lifecycle helpers for navigation, evaluation, and screenshots. It builds Page.navigate, Runtime.evaluate, Page.captureScreenshot, and DOM.scrollIntoView parameters, and can wait for selectors or elements.
Usage Examples
Run the demo
python demo.py
Connect to a running Chrome instance
from cdp_toolkit import CDPClient
client = CDPClient("127.0.0.1", 9222)
print(client.list_targets())
Fill a React form
from cdp_toolkit import CDPClient, CDPInput
client = CDPClient("127.0.0.1", 9222)
tab = client.create_target("https://example.com")
js = CDPInput.native_setter_js("#email", "user@example.com")
client.evaluate(tab["id"], js)
Click and drag
from cdp_toolkit import CDPClient, CDPMouseEvents
client = CDPClient("127.0.0.1", 9222)
# Click at (200, 300)
client.evaluate(tab_id, CDPMouseEvents.click(200, 300))
# Drag from (100, 100) to (400, 300)
client.evaluate(tab_id, CDPMouseEvents.drag(100, 100, 400, 300))
Navigate and take a screenshot
from cdp_toolkit import CDPClient, CDPNavigation
client = CDPClient("127.0.0.1", 9222)
client.navigate(tab_id, "https://example.com")
b64 = client.screenshot(tab_id)
Run the tests
python -m pytest tests/ -v
Quick Start
from cdp_toolkit import CDPClient
# Connect to a Chrome instance with --remote-debugging-port=9222
client = CDPClient("127.0.0.1", 9222)
# List open tabs
tabs = client.list_targets()
for tab in tabs:
print(f"{tab['id'][:8]} | {tab['url'][:60]}")
# Create a new tab
new_tab = client.create_target("https://example.com")
# Navigate
client.navigate(new_tab['id'], "https://httpbin.org/forms/post")
# Execute JavaScript
title = client.evaluate(new_tab['id'], "document.title")
print(f"Page title: {title}")
React/Vue Form Filling
The most common CDP use case: filling forms on React/Vue/Angular sites where standard input.value = "x" does not trigger reactivity.
from cdp_toolkit import CDPInput
# Generate native setter JavaScript for React
js_code = CDPInput.native_setter_js(
selector="#email",
value="user@example.com"
)
# Execute via CDP — triggers React's onChange handler
# For Vue.js
js_code = CDPInput.vue_setter_js(
selector="input[name='phone']",
value="+1234567890"
)
# Key-by-key typing simulation
js_code = CDPInput.simulate_typing(
selector="#search",
text="hello world",
delay_ms=50
)
Mouse Events
from cdp_toolkit import CDPMouseEvents
# Click at coordinates
params = CDPMouseEvents.click(x=200, y=300)
# Right-click
params = CDPMouseEvents.click(x=200, y=300, button="right")
# Double-click
params = CDPMouseEvents.double_click(x=200, y=300)
# Drag and drop
params = CDPMouseEvents.drag(
start_x=100, start_y=200,
end_x=400, end_y=300
)
Navigation and Screenshots
from cdp_toolkit import CDPNavigation
# Navigate and wait for load
client.navigate_and_wait(tab_id, "https://example.com")
# Take screenshot
screenshot_b64 = client.screenshot(tab_id)
# Scroll to element
js = CDPNavigation.scroll_to_element("#footer")
client.evaluate(tab_id, js)
# Wait for selector
js = CDPNavigation.wait_for_selector(".result-card", timeout_ms=5000)
Anti-Detection
CDP Toolkit includes JavaScript snippets to make automation less detectable:
from cdp_toolkit import stealth
# Remove webdriver flag
client.evaluate(tab_id, stealth.remove_webdriver_flag())
# Override navigator properties
client.evaluate(tab_id, stealth.override_navigator())
# Add realistic timing jitter
CDPInput.set_typing_delay(min_ms=30, max_ms=120)
Docker Integration
Run Chrome in Docker and control it with CDP Toolkit:
# Dockerfile
FROM chrome/headless
EXPOSE 9222
CMD ["chrome", "--remote-debugging-port=9222", "--no-sandbox"]
# Connect to Docker Chrome
client = CDPClient("chrome-container", 9222)
Testing
python -m pytest tests/ -v --tb=short
39 tests covering all modules. Zero external dependencies in tests.
API Reference
CDPClient
| Method | Description |
|---|---|
list_targets() |
List all open tabs/pages |
create_target(url) |
Open a new tab |
close_target(id) |
Close a tab |
activate_target(id) |
Focus a tab |
navigate(id, url) |
Navigate to URL |
evaluate(id, js) |
Execute JavaScript |
screenshot(id) |
Capture page screenshot |
CDPInput
| Method | Description |
|---|---|
native_setter_js(sel, val) |
React-compatible value setter |
vue_setter_js(sel, val) |
Vue.js-compatible value setter |
simulate_typing(sel, text, delay) |
Human-like typing simulation |
key_event(key) |
Send keyboard event |
CDPMouseEvents
| Method | Description |
|---|---|
click(x, y, button) |
Mouse click |
double_click(x, y) |
Double click |
drag(sx, sy, ex, ey) |
Drag and drop |
hover(x, y) |
Mouse hover |
License
MIT — see LICENSE
Links
Hire on LaborX: https://laborx.com/gigs/python-automation-telegram-bots-cdp-api-integrations-105867
Real-World Use Cases
- LaborX batch apply: 270+ job applications via JWT Bearer + SOCKS5
- Kwork dialog monitoring: CDP9224 conversation tracking at scale
- Gmail API: OAuth2 automation for inbox monitoring across accounts
- Freelance pipeline: Automated bid → apply → track → report system
- Bug bounty recon: Subdomain enumeration + evidence collection
Articles
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cdp_toolkit-1.4.1.tar.gz.
File metadata
- Download URL: cdp_toolkit-1.4.1.tar.gz
- Upload date:
- Size: 16.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c2c0172a725ed13198fce9ddec39e959ed94caae1cf5e2201f7b3017a0894b72
|
|
| MD5 |
5521b17a9973dc61769fed138bc6f0ff
|
|
| BLAKE2b-256 |
3f87b3544d8e16e9d00a7426a040b3da24d0d1a93bcc5db209bfc63298c451f5
|
File details
Details for the file cdp_toolkit-1.4.1-py3-none-any.whl.
File metadata
- Download URL: cdp_toolkit-1.4.1-py3-none-any.whl
- Upload date:
- Size: 10.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b3869944c2c6454d31016822f93216f46b442c0af4175f06a808723548f6a0ae
|
|
| MD5 |
10450b0abe19758bc0ea830d7d4a6664
|
|
| BLAKE2b-256 |
e564226cd772238d394fa641792cb0af0169ce882d177f557b6d61c2ddf8e59c
|