Patchright is an undetected Python version of the Playwright testing and automation library (version 1.58.2). It serves as a drop-in replacement for Playwright, specifically designed to bypass modern anti-bot detection systems by patching Chrome DevTools Protocol (CDP) leaks and browser fingerprinting issues. The library is actively maintained and receives updates to combat evolving detection techniques.
Install & Compatibility
Where this runs
tested against v0.0.1 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
156MB installed
● package 156MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
To utilize Patchright's stealth features, import directly from `patchright.sync_api` instead of `playwright.sync_api`.
from patchright.sync_api import sync_playwright
For asynchronous operations with Patchright's stealth, import from `patchright.async_api`.
from patchright.async_api import async_playwright
This quickstart demonstrates both synchronous and asynchronous usage of Patchright, highlighting the recommended configuration for maximum undetectability. It launches a persistent Chrome browser in non-headless mode, navigates to example.com, captures the page title and an H1 element's text, and takes a screenshot. The `user_data_dir` is made configurable via an environment variable for testing persistence. Remember to run `patchright install chrome` before executing.
import os
import asyncio
from patchright.sync_api import sync_playwright
def run_sync_example():
with sync_playwright() as p:
# Recommended configuration for maximum undetectability:
# Use launch_persistent_context with channel='chrome' and headless=False
# viewport=null (or no_viewport=True) prevents setting a fixed viewport, aiding stealth.
# user_data_dir is crucial for persisting cookies/session info if solving captchas manually.
user_data_dir = os.environ.get('PATCHRIGHT_USER_DATA_DIR', '/tmp/patchright_profile')
browser = p.chromium.launch_persistent_context(
user_data_dir=user_data_dir,
channel="chrome",
headless=False,
viewport=None, # equivalent to no_viewport=True
# Do NOT add custom browser headers or user_agent here, Patchright handles it.
)
page = browser.new_page()
try:
print(f"Navigating to example.com with {p.chromium.name}...")
page.goto("https://example.com")
print(f"Page title: {page.title()}")
# Example interaction: get text from an element
text = page.locator('h1').inner_text()
print(f"H1 text: {text}")
page.screenshot(path=f"example-{p.chromium.name}.png")
print("Screenshot saved.")
finally:
browser.close()
print("Browser closed.")
async def run_async_example():
async with async_playwright() as p:
user_data_dir = os.environ.get('PATCHRIGHT_USER_DATA_DIR_ASYNC', '/tmp/patchright_profile_async')
browser = await p.chromium.launch_persistent_context(
user_data_dir=user_data_dir,
channel="chrome",
headless=False,
viewport=None
)
page = await browser.new_page()
try:
print(f"Navigating to example.com (async) with {p.chromium.name}...")
await page.goto("https://example.com")
print(f"Page title (async): {await page.title()}")
text = await page.locator('h1').inner_text()
print(f"H1 text (async): {text}")
await page.screenshot(path=f"example-async-{p.chromium.name}.png")
print("Screenshot saved (async).")
finally:
await browser.close()
print("Browser closed (async).")
if __name__ == "__main__":
print("--- Running Synchronous Example ---")
run_sync_example()
print("\n--- Running Asynchronous Example ---")
# Make sure to install browsers: `patchright install chrome`
asyncio.run(run_async_example())
patchright --version
Upgrade
Version history
Breaking-change detection hasn't run for this library yet.
Audit
Security & dependencies
CVE tracking and dependency tree are planned for a later release.