TL;DR
- Patchright controls Chromium, but browser automation alone does not provide a CAPTCHA response.
- Patchright evaluates scripts in an isolated environment by default; reCAPTCHA configuration created in the page's main JavaScript environment may therefore be invisible.
- A small adapter can route only the Core SDK's evaluation calls to the main environment while keeping navigation and ordinary locators on the raw Patchright page.
- The executed check detected Google's public reCAPTCHA v2 test widget through that adapter. It did not perform a paid solve, token fill-back, or target-application verification.
- Validate detection first, then test solving with your own credential on an authorized application, and treat application acceptance as a separate outcome.
A Patchright script can load a page, locate a form, and still stop at a CAPTCHA widget. Changing the browser-control library does not create the response expected by the widget or by the application backend.
This tutorial connects a Python Patchright session to CapSolver through the official Core SDK. The important integration detail is JavaScript execution context: a visible widget and a page-owned global do not always appear in the same evaluation environment.
The runnable example keeps one page open, adapts SDK evaluation to the main page environment, and verifies detection on a local development fixture. Use this pattern only on pages you own or are authorized to automate.
What Patchright is and when a CAPTCHA solver helps
Patchright is a community-maintained Playwright derivative with a similar Python interface. Its official Python repository documents a replacement import, Chromium support, and the absence of Firefox and WebKit support.
Patchright owns browser navigation, element interaction, and the page lifetime. A CAPTCHA solver has a narrower responsibility: read the supported challenge inputs and, when properly authorized and credentialed, request a solution. Your application workflow must still decide whether its intended form submission or later page state actually succeeded.
That separation prevents several common mistakes. A successful navigation does not mean the CAPTCHA is resolved. A returned token does not mean the form was submitted. Token fill-back does not mean the application accepted the result. The CAPTCHA glossary gives additional context for that verification boundary.
For routine tests of software you control, use the CAPTCHA vendor's development settings when possible. Treat paid solver integration as a separate, explicitly authorized validation path rather than a default dependency for every browser test.
Why reCAPTCHA detection needs the right page context
Some reCAPTCHA detection paths depend on configuration created by the widget inside the page's main JavaScript environment. Patchright's evaluate() option isolated_context defaults to True, so an ordinary evaluation may not see page-owned globals even while the widget is visible in the DOM.
The controlled comparison used for this guide produced three useful observations:
- Unadapted SDK detection returned zero descriptors.
- The isolated evaluation could not see
window.___grecaptcha_cfg. - Evaluation with
isolated_context=Falsecould see the configuration, and SDK detection through the adapter returnedreCaptchaV2.
That means an empty result should trigger a context and initialization check before anyone changes the site key or repeats a solving request.
The adapter below forwards the SDK's evaluation calls to the page's main environment. It does not patch the installed Patchright package, globally disable isolation, or change navigation and locator behavior. The raw page remains responsible for normal browser work; only the object given to the SDK uses the wrapper.
This is a tested integration example for the pinned versions below, not a claim of an official Patchright partnership or universal compatibility with every future release.
Install the packages and check prerequisites
The executed example used Python 3.12, Patchright 1.64.1, and capsolver-core 0.1.1. Create an isolated environment and install Patchright's Chromium runtime:
python3 -m venv .venv
source .venv/bin/activate
python -m pip install "patchright==1.64.1" "capsolver-core==0.1.1"
python -m patchright install chromium
Pinning the versions makes the small setup check reproducible and keeps package upgrades from silently changing the adapter's assumptions.
No CapSolver API key is required for detection. Actual solving requires your own valid key and sufficient account resources. Initialize the SDK with the documented create_capsolver(api_key=...) option and load the key from approved secret configuration, never source control. The Core SDK guide documents client creation, detection, solving, and result fields.
The local test uses Google's public reCAPTCHA development key. It is not a private credential or a production target. Paid solving, token fill-back, and target-application acceptance were not executed in this guide.
Run a local Patchright and SDK setup check
This setup check opens a locally routed page, waits for Google's public test widget, and prints the parameters found by the official SDK. Save it as patchright_sdk_check.py.
The browser route means no separate web server is required, although Chromium still needs network access to Google's widget script. The public site key comes from Google's reCAPTCHA testing guidance.
import asyncio
import json
from capsolver_core import create_capsolver
from patchright.async_api import async_playwright
TEST_URL = "http://127.0.0.1:8765/"
HTML = """<!doctype html><html><head><title>CAPTCHA integration check</title></head>
<body><h1>Owned development page</h1>
<div class="g-recaptcha" data-sitekey="6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI"></div>
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
</body></html>"""
class MainWorldPage:
def __init__(self, page):
self._page = page
@property
def url(self):
return self._page.url
async def evaluate(self, expression, arg=None):
return await self._page.evaluate(expression, arg, isolated_context=False)
async def wait_for_selector(self, selector, **kwargs):
return await self._page.wait_for_selector(selector, **kwargs)
async def main():
async with async_playwright() as p:
browser = await p.chromium.launch(headless=True)
try:
raw_page = await browser.new_page()
await raw_page.route(
TEST_URL, lambda route: route.fulfill(content_type="text/html", body=HTML)
)
await raw_page.goto(TEST_URL)
page = MainWorldPage(raw_page)
for _ in range(60):
ready = await page.evaluate(
"() => !!window.___grecaptcha_cfg && "
"Object.keys(window.___grecaptcha_cfg.clients || {}).length > 0"
)
if ready:
break
await asyncio.sleep(0.5)
else:
raise RuntimeError("Test widget did not initialize")
async with create_capsolver() as cap:
infos = await cap.get_captcha_info(page)
result = [{"type": info.type.value, "url": info.website_url,
"site_key": info.website_key} for info in infos]
print(json.dumps({"captcha_parameters": result}))
assert result and result[0]["type"] == "reCaptchaV2"
finally:
await browser.close()
if __name__ == "__main__":
asyncio.run(main())
The executed run returned one reCaptchaV2 descriptor with the local URL and Google's public test site key. That verifies the actual Patchright browser, the main-environment adapter, and Core SDK detection. The SDK output was not mocked.
The result contains no solution token and says nothing about whether a production form would accept one. The browser and SDK both close through their asynchronous contexts, while finally also closes the browser after a widget or detection failure. Keep equivalent cleanup in longer-running automation.
Add solving after the detection check
Solving must run while the SDK client and current wrapped page are both still alive. On your authorized application page, create a credentialed SDK client, adapt the current Patchright page as above, and then use the official browser-mode call.
The following official line is unchanged. It requires a configured CapSolver API key. Paid execution with this Patchright adapter was not tested for this tutorial.
results = await cap.solve_on_page(page)
Inspect each result before continuing. The SDK exposes fields including error, solution, and filled, allowing the application to distinguish a failed attempt, a returned solution, and token fill-back. Do not submit the form if a required solution is missing or the relevant result reports an error.
For reCAPTCHA v2-specific task requirements, consult the official documentation. Confirm that the descriptor still belongs to the intended current page; a site key copied from another environment or stale page state is not a valid substitute.
Confirm the application result before continuing
After solving and fill-back, your workflow may still need to submit a form, wait for a callback, or navigate to a result. Google's server-side verification guidance explains why the application must validate the response.
Define a success signal from software you control—for example, an expected confirmation message in a staging application—and stop when it does not appear. Do not treat an HTTP response, a token string, or filled=True as end-to-end browser-task success.
If the page rejects the response, preserve a redacted error summary, inspect the failing stage, and avoid blind retries. CapSolver's guide to CAPTCHA tokens and cookies provides additional output context.
Troubleshoot empty detection and failed continuation
Start at the first failed stage: page loading, widget initialization, JavaScript context access, solving, fill-back, or application acceptance.
| Symptom | Check first |
|---|---|
| The test widget never initializes | Confirm that Chromium can load Google's script and that the widget exists on the intended page. |
| The widget is visible but detection is empty | Confirm that the SDK receives MainWorldPage and that main-environment evaluation works for the pinned versions. |
| The SDK returns an error | Read the documented error, check the credential and task inputs, and do not repeat the same invalid request. |
| A solution exists but fill-back is false | Inspect the supported challenge path and current page state before submitting. |
| Fill-back succeeds but the workflow stops | Check the normal form action, callback behavior, and the application's own result signal. |
Start with one page and one attempt. Add bounded retries only after identifying which failures are temporary. Reusing a result after navigation can associate it with the wrong page state, while repeating the same invalid request can add cost without fixing the cause.
Test Patchright and SDK upgrades together. A familiar Playwright-like interface does not guarantee identical behavior for every SDK or extension that evaluates page JavaScript. Keep the small detection script as a compatibility check, then run a separate credentialed solve-and-application validation against your own authorized environment before production use.
Finish the integration with an application check
A reliable Patchright integration connects three things: the current browser page, a supported CAPTCHA operation, and an observable application result. Validate page-context access first, test paid solving separately with your own credential, and allow the larger workflow to continue only after the application confirms the intended action.
That keeps CapSolver focused on the CAPTCHA step instead of turning every navigation or form problem into an assumed challenge.
Build Reliable Automation Workflows with CapSolver
Use CapSolver only when an actual supported CAPTCHA interrupts an authorized Patchright workflow. Protect credentials, retain the page state needed for the operation, bound attempts, and verify the application outcome before increasing workload.
The official source link and canonical URL will be added after publication: 待官网发布后补入.
FAQ
Q: Does Patchright solve reCAPTCHA by itself?
No. Browser control does not create a solution token. Use an authorized solver step or the application's development CAPTCHA settings when appropriate.
Q: Why can a visible widget produce an empty result?
The script may be evaluating an isolated JavaScript environment instead of the main environment where the widget created its configuration. Check initialization and context access first.
Q: Is this an official Patchright integration?
No. It is an integration example using the official Patchright package and CapSolver SDK. The adapter and detection script were executed with the listed versions; paid solving was not tested.
Q: Does the local check need an API key?
No. It reads parameters from a public development widget. The separate solving call requires a valid key and account resources.
Q: Can this example use Firefox or WebKit?
No. Patchright documents Chromium-based browser support for this package, and the example launches Chromium.
Q: Does token fill-back mean the form passed?
No. Fill-back and application acceptance are separate. Run the required action and check the application's response before continuing.

Top comments (0)