Skip to main content
Peak — solve Cloudflare Turnstile & the 5s challenge in ~1s

playwright-turnstile

playwright-turnstile is a Playwright helper that solves Cloudflare Turnstile for you: it reads the sitekey off the page, gets a token from Peak, and injects it so your submit or navigation goes through.

from playwright_turnstile import solve_turnstile

token = await solve_turnstile(page, api_key="pk_your_api_key")

Why

playwright-stealth is a proof of concept. Even with a patched, real browser, interactive Turnstile still fails from headless and datacenter environments: the widget scores the session, sees a datacenter IP with no trusted history, and holds you at the "Verifying..." spinner or an endless challenge. Clicking the checkbox harder does not help, because the token you need is issued by Cloudflare's risk engine, not by the click.

So this package does not click. It reads the Turnstile sitekey from the DOM, hands it to Peak, and injects the returned token into cf-turnstile-response while firing the widget's success callback. When your setup gets blocked, drop in a Peak API key and it just works.

Powered by Peak

This package uses Peak to solve Turnstile.

  • Solve Cloudflare Turnstile & the 5s challenge in about a second
  • $0.90 per 1,000 successful Turnstile solves, down to $0.35 at volume
  • 1,000 free solves to start, no card.

→ Get your free API key · Docs · Pricing

Install

pip install playwright-turnstile playwright
playwright install chromium

The core package has no runtime dependencies; playwright is the one you drive it with.

Quickstart

import asyncio
from playwright.async_api import async_playwright
from playwright_turnstile import solve_turnstile

async def main():
    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=True)
        page = await browser.new_page()
        await page.goto("https://protected.example/login")

        # Reads the sitekey, solves via Peak, injects the token.
        await solve_turnstile(page, api_key="pk_your_api_key")

        await page.click("button[type=submit]")
        await page.wait_for_load_state("networkidle")
        await browser.close()

asyncio.run(main())

Set your key once and let it read from the environment:

export PEAK_API_KEY=pk_your_api_key   # Windows: set PEAK_API_KEY=pk_your_api_key
await solve_turnstile(page)  # picks up PEAK_API_KEY

API

await solve_turnstile(page, api_key=None, proxy=None, sitekey=None, timeout=180.0)

Solve the Turnstile challenge on a Playwright async Page. Returns the token (also injected into the page).

  • page — a Playwright async Page on a Turnstile-protected URL.
  • api_key — Peak key (pk_...). Falls back to the PEAK_API_KEY env var.
  • proxy — optional proxy passed to Peak, e.g. http://user:pass@ip:port. Use the same egress IP as your browser so the token matches the session.
  • sitekey — override the sitekey instead of reading it from the DOM.
  • timeout — seconds to wait for Peak.

solve_turnstile_sync(page, ...)

Same signature, for Playwright's sync API (sync_playwright). Blocking.

from playwright_turnstile import solve_turnstile_sync

with sync_playwright() as p:
    page = p.chromium.launch().new_page()
    page.goto("https://protected.example/login")
    solve_turnstile_sync(page, api_key="pk_your_api_key")

How it works

  1. Reads the sitekey from the widget (.cf-turnstile[data-sitekey], any [data-sitekey], or the challenges.cloudflare.com iframe src) via query_selector / evaluate.
  2. Calls Peak POST https://api.peak.fo/solve with task_type: "turnstiletask", the sitekey, url: page.url, and your optional proxy.
  3. Injects the returned token into every cf-turnstile-response field (creating a hidden input if the widget has not yet) and invokes the widget's data-callback, so your form submit or navigation proceeds.

Peak also supports the Cloudflare 5s challenge (task_type: "cloudflare5stask"); this package focuses on Turnstile.

Legitimate use

Built for automation, QA, and scraping public data. Respect each target's Terms of Service and robots.txt, and do not use it for credential-stuffing or other abuse. You are responsible for how you use it.

License

MIT — see LICENSE.

Metadata

Release files for playwright-turnstile 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for playwright-turnstile 0.1.1
File Size Uploaded
playwright_turnstile-0.1.1.tar.gz 9.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for playwright-turnstile 0.1.1
File Interpreter ABI Platform
playwright_turnstile-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 17.4 kB

Release files / playwright_turnstile-0.1.1.tar.gz

Download URL playwright_turnstile-0.1.1.tar.gz
Size 9.2 kB
Tags Source
SHA-256 checksum
How to use checksums
ea16d354f1d99afa7062166d47b0c12168ebf2ec323a2372af3f36b60ba14259
BLAKE2b-256 checksum
How to use checksums
94253eeaed6441672671b57a37099e76e57afc09d094f6f9b0fcf0c0b0133817
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.0

Release files / playwright_turnstile-0.1.1-py3-none-any.whl

Download URL playwright_turnstile-0.1.1-py3-none-any.whl
Size 8.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8f14645bbde52095e463def9f4d625fbe1c6c8bdc230480cb9d14b65865a7dea
BLAKE2b-256 checksum
How to use checksums
8035126b0e4243cb33b82acd414811f53596a5b3b6370661f4b3b4bb0f4a8a12
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.0

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page