Browser Control
The cdp.browser_control module provides a high-level browser automation
API built on top of the raw CDP domain modules and
CDPConnection. It offers a set of coroutines
similar to what Playwright or Puppeteer expose, without requiring an external
automation framework.
Note
This module requires the websockets dependency. Install it with:
pip install chrome-devtools-protocol[io]
Quick Start
import asyncio
from cdp.connection import CDPConnection
from cdp import browser_control as bc
from cdp import page
async def main():
async with CDPConnection("ws://localhost:9222/devtools/page/ID") as conn:
# Enable page events (required for wait_for_load)
await conn.execute(page.enable())
# Navigate and wait for the page to load
await bc.navigate(conn, "https://example.com")
await bc.wait_for_load(conn)
# Read the heading text
text = await bc.get_text(conn, "h1")
print(f"Heading: {text}")
# Click a link
await bc.click(conn, "a")
# Fill a form
await bc.clear_and_type(conn, "input[name='q']", "hello world")
await bc.press_key(conn, "Enter")
# Capture a screenshot
png_bytes = await bc.screenshot(conn)
with open("page.png", "wb") as f:
f.write(png_bytes)
asyncio.run(main())
Element Selection
Element Interaction
Element Inspection
Screenshots
JavaScript
Waiting
Patterns and Recipes
Waiting for an element before interacting
node = await bc.wait_for_selector(conn, "#submit-button", timeout=10)
await bc.click(conn, node)
Checking visibility before clicking
if await bc.is_visible(conn, ".cookie-banner"):
await bc.click(conn, ".cookie-banner .dismiss")
Reading all list items
items = await bc.query_selector_all(conn, "ul.results li")
for node in items:
text = await bc.get_text(conn, node)
print(text)
Extracting a link href
href = await bc.get_attribute(conn, "a.download", "href")
Selecting a dropdown value
await bc.select_option(conn, "select#country", "US")
Keyboard shortcuts
# Ctrl+A then Delete
await bc.press_key(conn, "a", modifiers=2) # Ctrl=2
await bc.press_key(conn, "Delete")
Capturing a single element screenshot
png = await bc.screenshot_element(conn, "#logo")
with open("logo.png", "wb") as f:
f.write(png)
Running arbitrary JavaScript
count = await bc.evaluate(conn, "document.querySelectorAll('li').length")
print(f"Found {count} list items")
# Operate on a specific element
checked = await bc.evaluate_on_node(
conn, "input[type='checkbox']",
"function() { return this.checked; }"
)