DrissionPage and Cloudflare Turnstile
DrissionPage is a well-built Chinese automation library with a design idea the Western ecosystem mostly lacks: one object model that switches between driving a browser and sending plain HTTP, so you use a browser only for the parts that need one. It also handles shadow roots that are not in open state, which is where a Turnstile checkbox lives. Two things to establish before you build on it: its licence forbids commercial use, and its documentation is Chinese-only.
The licence, first, because it is disqualifying for some readers
The README and the package's own __init__.py docstring both carry terms that GitHub cannot classify — which is why the repository shows NOASSERTION rather than a licence name. Translated, they permit personal use "for study and lawful non-profit purposes only", and state that individuals or organisations may not use the project in source or binary form for commercial activity without the copyright holder's authorisation.
That is not an OSI-style open-source licence, and it is a meaningfully different position from the MIT and Apache terms that Patchright, chromedp and most of this ecosystem use. If DrissionPage is going into anything commercial, that is a conversation to have before it becomes load-bearing, not after.
The same terms also forbid use that violates local law or is aimed at attack or harassment, and require respecting robots.txt. Worth reading in full rather than taking this summary's word for it.
What it is, and the idea worth stealing
The name is the design. SessionPage sends HTTP requests. ChromiumPage drives a browser. WebPage is both, with the same element-finding API over either — so a crawl can do the cheap parts as requests and switch to a browser only where rendering is genuinely required, without rewriting the extraction code.
Its README lists advantages over Selenium that are mostly accurate and mostly about ergonomics: no webdriver, so no driver binary to match to a browser version; finding elements across iframes without switching in and out; operating multiple tabs without switching; and — the one that matters here — handling shadow-root elements that are not in open state.
That last capability puts it in the same small group as Patchright: tools that can reach inside a closed shadow root, which is a precondition for touching a Turnstile widget at all rather than a defeat of it.
from DrissionPage import ChromiumPage page = ChromiumPage() page.get("https://app.example.com/login") # NOTE: index starts at 1, not 0 — this catches everyone once el = page.ele("css:input[name=username]", index=1) el.input("someone@example.com")
ele(locator, index=1) — the index is one-based. Every other library in this space is zero-based, and the resulting off-by-one is quiet rather than loud.
It has no Turnstile handling
This is worth stating flatly, because the shadow-root capability leads people to expect otherwise. The published package contains zero occurrences of turnstile or captcha in any code. The only matches for cloudflare anywhere in it are domain entries inside a public-suffix data file — incidental, not functional.
So what DrissionPage gives you is reach, not a solution. You can locate an element inside the widget's structure; whether an interaction with it is accepted is decided by everything else, and Cloudflare's position on automated browsers solving production challenges is that they are not supported.
Setting a value is input(...), and by_js=True is the documented way to do it through JavaScript rather than simulated keystrokes — the equivalent of execute_script elsewhere. The docstring notes by_js cannot send key combinations, which is the trade-off:
import json, os, urllib.request from DrissionPage import ChromiumPage SITEKEY = "0x4AAAAAAA_target" PAGE = "https://app.example.com/login" req = urllib.request.Request( "https://api.solvegate.io/v1/solve", data=json.dumps({"gate": "turnstile", "sitekey": SITEKEY, "url": PAGE}).encode(), headers={ "Authorization": f"Bearer {os.environ['SOLVEGATE_KEY']}", "Content-Type": "application/json", }, ) with urllib.request.urlopen(req, timeout=30) as res: token = json.load(res)["token"] page = ChromiumPage() page.get(PAGE) page.run_js( """ const el = document.querySelector('[name="cf-turnstile-response"]'); el.value = arguments[0]; el.dispatchEvent(new Event('input', { bubbles: true })); """, token, )
The documentation situation
There is no official English documentation. The canonical site is Chinese-only — the /en/ path returns 404 — and the README is entirely in Chinese. The most complete third-party mirror found is also Chinese.
This is not a criticism; it is a planning fact. If nobody on the team reads Chinese, every API question becomes a machine-translation round trip, and the subtleties that matter — like the one-based index above — are exactly the kind that survive translation badly. Budget for it, or pick a tool documented in a language your team reads.
The library itself is substantial: over twelve thousand stars, actively pushed, Python 3.6+, and supporting Chromium-based browsers plus Electron applications.
Where it fits
| If you need | DrissionPage is |
|---|---|
| Mixed HTTP and browser work in one API | Genuinely good — this is its distinctive idea |
| Access inside closed shadow roots | Capable — one of few that state this |
| Commercial deployment | Blocked by its licence terms without authorisation |
| English documentation | Not available |
| Any Turnstile-specific handling | Not present — no such code in the package |
If the target is your own property and the widget is only in the way of a test, Cloudflare's dummy sitekeys remove the challenge from the test entirely, which is both simpler and their own recommendation.
If it has to clear, a token typically returns in under 1.5 seconds and the request is the same whatever drives the browser. Prepaid credits run from $0.40 per 1,000 down to $0.075 at volume; failed solves are never billed; the first 1,000 are free. The solve reference has the call.
Common questions
Not without the copyright holder's authorisation. Its terms permit personal use for study and lawful non-profit purposes and state that individuals or organisations may not use it in source or binary form for commercial activity. GitHub reports the licence as NOASSERTION because it is not a standard open-source licence.
No. The published package contains no turnstile or captcha code at all — the only cloudflare matches are domain entries in a public-suffix data file. What it offers is the ability to reach elements inside non-open shadow roots, which is a reachability capability rather than a solution.
No official English documentation exists. The canonical documentation site is Chinese-only and its /en/ path returns 404, and the README is entirely in Chinese. Plan for machine translation, or choose a library documented in a language your team reads.
SessionPage sends plain HTTP requests, ChromiumPage drives a browser, and WebPage is both behind one element-finding API. That is the library's distinctive idea: do the cheap parts as requests and switch to a browser only where rendering is genuinely needed, without rewriting the extraction code.
Its index parameter is one-based, not zero-based — index=1 is the first match. Every comparable library is zero-based, so the off-by-one is easy to introduce and it fails quietly by selecting the wrong element rather than raising.
Related
Sources
More in Guides
Automating a gate you own or are authorised to test?
// SolveGate clears Cloudflare Turnstile and WAF challenges through one REST call · first 1,000 solves free