Skip to main content

Patchright Python wrapper with optional Turnstile auto-click helper.

Project description

patchright-difz

Patchright Python wrapper with an optional Turnstile helper.

Install

pip install patchright-difz

Sync usage

from patchright_difz.sync_api import sync_playwright

with sync_playwright() as p:
    context = p.chromium.launch_persistent_context(
        ".profile",
        headless=False,
        channel="chrome",
        no_viewport=True,
        turnstile=True,
    )
    page = context.new_page()
    page.goto("https://example.com")

Async usage

from patchright_difz.async_api import async_playwright

async with async_playwright() as p:
    context = await p.chromium.launch_persistent_context(
        ".profile",
        headless=False,
        channel="chrome",
        no_viewport=True,
        turnstile=True,
    )
    page = await context.new_page()
    await page.goto("https://example.com")

page.evaluate, frame.evaluate, locator evaluate helpers, and handle evaluate helpers default to the page main world in this wrapper. If you need Patchright's isolated world for a specific call, pass isolated_context=True.

The Turnstile helper uses Patchright locators for fallback detection, so it can also pick up challenge candidates rendered inside closed shadow roots. The hidden cf-turnstile-response field is only used as optional token/data evidence; active challenge detection prefers visible widgets, iframes, and clickable candidates.

When headless=True is used without a custom user_agent, the wrapper sets a normal Chrome user agent before the first request. This applies to launch_persistent_context, browser.new_context, and browser.new_page. Set PATCHRIGHT_DIFZ_HEADLESS_USER_AGENT=0 to keep Patchright's default headless user agent, or set it to a full user-agent string to override the default.

Configure Turnstile

context = p.chromium.launch_persistent_context(
    ".profile",
    headless=False,
    channel="chrome",
    no_viewport=True,
    turnstile={
        "timeout_ms": 5000,
        "interval_ms": 750,
        "foreground": True,
        "click_delay_ms": 35,
        "mouse_move_steps": 8,
        "logger": print,
    },
)

Camel-case option names from the npm package are also accepted: timeoutMs, intervalMs, maxCandidatesPerSelector, clickDelayMs, mouseMoveSteps, and waitAfterClickMs.

Manual usage

from patchright_difz.sync_api import check_turnstile, sync_playwright

with sync_playwright() as p:
    context = p.chromium.launch_persistent_context(
        ".profile",
        headless=False,
        channel="chrome",
        no_viewport=True,
    )
    page = context.new_page()
    page.goto("https://example.com")
    check_turnstile(page)

Turnstile and Cloudflare data helpers

from patchright_difz.sync_api import (
    get_cloudflare_data,
    has_turnstile,
    is_turnstile_solved,
)

exists = has_turnstile(page)
solved = is_turnstile_solved(page)
data = get_cloudflare_data(page)

print({
    "exists": exists,
    "solved": solved,
    "cookies": data["cloudflare_cookies"],
    "clearance": data["clearance_cookie"],
    "cleared": data["challenge"]["cleared"],
    "document_cookie_names": data["document_cookie_names"],
    "tokens": data["turnstile"]["tokens"],
    "sitekeys": data["turnstile"]["sitekeys"],
    "responses": data["turnstile"]["responses"],
})

Async usage uses the same names with await:

from patchright_difz.async_api import get_cloudflare_data

data = await get_cloudflare_data(page)

get_cloudflare_data reads the current browser context cookies plus visible page data such as Turnstile response fields, widget sitekey values, Cloudflare iframe/script URLs, challenge fields, Ray IDs, and Cloudflare-related local/session storage keys. Pass context and urls when you only want cookie data for specific URLs:

data = get_cloudflare_data(
    context=context,
    urls=["https://example.com"],
)

Publish

python scripts/publish.py

The command builds, creates a v<version> git tag, pushes to GitHub, and lets the GitHub Actions workflow publish to PyPI through Trusted Publishing.

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

patchright_difz-0.4.1.tar.gz (15.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

patchright_difz-0.4.1-py3-none-any.whl (21.8 kB view details)

Uploaded Python 3

File details

Details for the file patchright_difz-0.4.1.tar.gz.

File metadata

  • Download URL: patchright_difz-0.4.1.tar.gz
  • Upload date:
  • Size: 15.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for patchright_difz-0.4.1.tar.gz
Algorithm Hash digest
SHA256 e6973a86c8f07849e9f0dd0361ceb4979cd6ea731923fecf0b4fa43450da7b23
MD5 bc73ed9a1a99d879b14941c319d9a748
BLAKE2b-256 659d3e5cc7ab5e8a48c70a30e46305a99c372593cf15d0c5323314fd4fdfebf5

See more details on using hashes here.

Provenance

The following attestation bundles were made for patchright_difz-0.4.1.tar.gz:

Publisher: publish.yml on Difz25x/patchright-difz-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file patchright_difz-0.4.1-py3-none-any.whl.

File metadata

  • Download URL: patchright_difz-0.4.1-py3-none-any.whl
  • Upload date:
  • Size: 21.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for patchright_difz-0.4.1-py3-none-any.whl
Algorithm Hash digest
SHA256 af8fc262b39e9365b0b7c58a2013b2031b55b4b5d1bbbecd3e7c9cf2db0f542e
MD5 f4445e2f2fad402734f7501b15f9ab46
BLAKE2b-256 c7844eda2c04907c379c634756de1ab5936c8b18dd14c736cf1d85cf04ac51ad

See more details on using hashes here.

Provenance

The following attestation bundles were made for patchright_difz-0.4.1-py3-none-any.whl:

Publisher: publish.yml on Difz25x/patchright-difz-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page