Quickstart¶
This tutorial takes about 10 minutes. You'll learn to launch Chrome, navigate, evaluate JavaScript, listen to events, manage multiple tabs, and clean up.
Install¶
cdpwave detects Chrome, Edge, Brave, or Chromium on your system. No browser download needed.
First script¶
import asyncio
from cdpwave import CDPClient
async def main() -> None:
async with await CDPClient.launch(headless=True) as client:
session = await client.new_page("https://example.com")
await session.page.enable()
result = await session.runtime.evaluate(
"document.title", return_by_value=True
)
print(result["result"]["value"]) # "Example Domain"
await session.close()
asyncio.run(main())
Run it:
Events¶
Listen to page events with async handlers:
import asyncio
from cdpwave import CDPClient
async def main() -> None:
async with await CDPClient.launch(headless=True) as client:
session = await client.new_page()
await session.page.enable()
loaded = asyncio.Event()
async def on_load(_: dict) -> None:
loaded.set()
session.on("Page.loadEventFired", on_load)
await session.page.navigate("https://example.com")
await asyncio.wait_for(loaded.wait(), timeout=10.0)
print("Page loaded!")
await session.close()
asyncio.run(main())
Multi-tab¶
Open multiple tabs concurrently — all share a single WebSocket:
import asyncio
from cdpwave import CDPClient
async def fetch_title(client: CDPClient, url: str) -> str:
session = await client.new_page(url)
result = await session.runtime.evaluate("document.title", return_by_value=True)
title = result["result"]["value"]
await session.close()
return title
async def main() -> None:
urls = ["https://example.com", "https://www.python.org"]
async with await CDPClient.launch(headless=True) as client:
tasks = [fetch_title(client, url) for url in urls]
titles = await asyncio.gather(*tasks)
for url, title in zip(urls, titles, strict=True):
print(f"{url} -> {title}")
asyncio.run(main())
Cleanup¶
CDPClient and CDPSession both support async with. When the context exits, everything is cleaned up — WebSocket closed, browser terminated, temp directory removed:
async with await CDPClient.launch(headless=True) as client:
async with await client.new_page() as session:
await session.page.navigate("https://example.com")
# session.close() called automatically
# client.close() called automatically — browser terminated
Even if an exception occurs inside the async with block, cleanup is guaranteed.
What's next?¶
- Guide: Browser Launch — launch options, connecting to existing browsers
- Guide: Events — handler isolation, subscriptions, common events
- Guide: Emulation & Input — device metrics, keyboard, mouse, touch
- Guide: Fetch & Network Interception — intercept, mock, block requests
- Guide: Performance & Profiling — CPU profiling, heap snapshots, tracing
- Guide: Debugging — breakpoints, stepping, variable inspection
- Guide: Storage & Cache — cookies, IndexedDB, Cache API
- Guide: Advanced Domains — Accessibility, CSS, Overlay, Security, WebAuthn, DOMSnapshot, DOMStorage, FedCM, WebAudio, and more
- Cookbook: Escape Hatch — send raw CDP commands
- API Reference — full auto-generated API docs for all 60 domains