CDP-Patches
CDP-Patches is a Python library designed for patching Chrome DevTools Protocol (CDP) leaks at the operating system level. It aimed to address issues like input domain leaks and the inability of CDP to dispatch coalesced events, making web automation with tools like Playwright and Selenium more robust against bot detection. Version 1.1, released on September 28, 2025, represents its latest and likely final iteration.
Common errors
-
CDP-Patches is not fixing my input leaks anymore / My bot is still detected despite using cdp-patches.
cause The underlying Chrome bug (crbug#1477537) that caused the input leak has been fixed in Chrome v142+. Your detection might be due to other factors, or the package's primary utility is no longer relevant for modern browsers.fixUpdate your Chrome browser to v142+ to benefit from native fixes. Review other aspects of your automation setup for bot detection vectors, as this library's core function is largely obsolete. -
ModuleNotFoundError: No module named 'cdp_patches.input' OR Cannot import SyncInput/AsyncInput
cause The `cdp-patches` library is either not installed or you are using an incorrect import path.fixEnsure the library is installed: `pip install cdp-patches`. Use the correct import statement: `from cdp_patches.input import SyncInput` or `from cdp_patches.input import AsyncInput`. -
AttributeError: 'WebDriver' object has no attribute 'get_pid' OR SyncInput(pid=None) error
cause `SyncInput` or `AsyncInput` was initialized without a valid browser `pid` or `browser` instance, or the `browser` object passed does not expose a `pid` compatible with the library's expectations, especially in older versions or non-standard setups.fixWhen initializing `SyncInput`, ensure you pass a valid `browser` object from Playwright/Selenium that `cdp-patches` can extract a PID from, or explicitly provide the browser's process ID: `sync_input = SyncInput(browser=driver)` (for Selenium) or `sync_input = SyncInput(pid=your_browser_pid)`.
Warnings
- breaking The primary 'Input Leak' (crbug#1477537) that this library aimed to fix has been resolved in Chrome-Stable v142+. CoalescedEvents are now also emitted by input events, rendering the main purpose of this package obsolete for modern Chrome versions.
- deprecated The official GitHub repository for cdp-patches has been archived by the owner, making it read-only. This indicates that the project is no longer actively maintained.
- gotcha Due to its reliance on OS-level events, `cdp-patches` can only be used with headful browsers. It will not function correctly with headless browser environments.
- gotcha The OS-level input methods implemented by `cdp-patches` are sensitive to system-level key presses. Manually pressing keys like SHIFT or CAPSLOCK on Windows can interfere with automated input.type(text) operations.
- gotcha Chrome does not recognize Input Events to specific tabs when dispatched at the OS level. Therefore, `cdp-patches` methods can only reliably be used on the currently active tab.
Install
-
pip install cdp-patches -
pip install cdp-patches[automation_linting]
Imports
- SyncInput
from cdp_patches.input import SyncInput
- AsyncInput
from cdp_patches.input import AsyncInput
Quickstart
import os
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
from cdp_patches.input import SyncInput
# NOTE: This example requires a ChromeDriver executable in your PATH
# and a headful Chrome browser to run, as cdp-patches works on OS-level events.
def get_locator_pos(locator: WebElement):
location = locator.location
size = locator.size
assert location and size
x, y, width, height = location.get("x"), location.get("y"), size.get("width"), size.get("height")
assert x is not None and y is not None and width is not None and height is not None
# Calculate center of the element
x, y = x + width // 2, y + height // 2
return x, y
options = webdriver.ChromeOptions()
# Disable logs & automation flags for stealth (recommended for general automation, not specific to cdp-patches)
options.add_experimental_option("excludeSwitches", ["enable-logging", "enable-automation"])
options.add_experimental_option("useAutomationExtension", False)
options.add_argument("--log-level=3")
# Ensure Chrome is launched headfully
# For local testing, ensure ChromeDriver is in PATH or specify service.executable_path
try:
with webdriver.Chrome(options=options) as driver:
# cdp-patches operates on the browser's process ID (PID) or WebDriver instance
sync_input = SyncInput(browser=driver)
driver.get("https://www.google.com")
# Example: Find a search bar and click it using OS-level input
search_bar = driver.find_element(By.NAME, "q")
x, y = get_locator_pos(search_bar)
print(f"Clicking search bar at: ({x}, {y})")
sync_input.click("left", x, y)
print("Successfully clicked element using CDP-Patches SyncInput.")
except Exception as e:
print(f"An error occurred: {e}")
print("Please ensure Chrome browser and ChromeDriver are installed and configured correctly.")
print("Also, remember cdp-patches requires a headful browser.")