Playwright handles waiting and frames better than older drivers, which removes half of the usual captcha friction: you can wait for the widget and reach into the iframe cleanly. What it does not do is answer the challenge, so the same pattern applies: read the sitekey, get a token from the API, inject it, submit.
Locators make this a single expression: locate the element by class, read the attribute, and if that is empty read the frame URL. For reCAPTCHA look for g-recaptcha, for hCaptcha for h-captcha, and for Turnstile for cf-turnstile. When the widget is created by script the attribute may appear a moment later, so wait for the attribute rather than the element.
Use page evaluate to set the value of the hidden field and then dispatch input and change events with bubbles enabled, because frameworks listen at the document level. If the page exposes a callback, call it through evaluate instead, passing the token. Injecting into the wrong mechanism is the most common reason a token is returned as valid but the form still refuses to submit.
One credit per accepted token, twenty for a reCAPTCHA token, with polling free and refused submissions uncharged. For flows that only need an occasional manual pass, the browser extension covers the same challenges with no Playwright code.
curl -X POST https://fuckcaptcha.top/v1/token/recaptcha2 \\
-H "Authorization: Basic $NSK_KEY" \\
-d '{"sitekey":"<sitekey>","url":"<page url>"}'
Charged per solve: one credit for each recognition request, and polling for the result is free. Signing up includes 200 free solves.
Better at the browser part: waiting, frames and isolated contexts reduce flakiness. The solve itself still comes from the API, so the two are complementary rather than competing.
Yes, and it is often the more reliable source. Take the src of the challenge iframe and read the sitekey from its query string, which also works when the outer element carries no attribute.
Request it immediately before you submit and do not reuse it across forms. Tokens are short lived, and the most common false failure is a token that was fetched too early.
Yes. Pass the proxy to the context and send the same value on the solve request, since sites that inspect addresses expect the two to agree.
There is nothing to wait for visually, so read the sitekey from the script configuration or the frame URL, get the token, and pass it to the page callback rather than into a field.