How to Identify Which CAPTCHA a Site Uses
Learn the DOM, script, window, and payload markers that identify each major CAPTCHA provider on a page.
Identifying the CAPTCHA provider on a page is straightforward, because each one must inject a recognisable container, load a script from its own domain, and post a distinctively named response field.
1. The Four Marker Classes
| Class | Where | Visible without JS? |
|---|---|---|
| DOM container | A div with a vendor class and data-sitekey |
Yes |
| Script URL | <script src> from the vendor's domain |
Yes |
| Window global | An object the script defines | No |
| Payload field | A named field on form submission | No |
The first two appear in the initial HTML, so a plain HTTP fetch identifies most CAPTCHAs without executing anything.
2. Provider Markers
| Provider | Container / class | Window global | Response field |
|---|---|---|---|
| reCAPTCHA | .g-recaptcha |
grecaptcha |
g-recaptcha-response |
| hCaptcha | .h-captcha |
hcaptcha |
h-captcha-response |
| Turnstile | .cf-turnstile |
turnstile |
cf-turnstile-response |
| FunCaptcha / Arkose | Arkose iframe | ArkoseEnforcement |
fc-token |
| GeeTest | .geetest_* |
initGeetest |
challenge / validate |
| Friendly Captcha | .frc-captcha |
β | frc-captcha-solution |
| Tencent / QCloud | Tencent script domain | TencentCaptcha |
ticket / randstr |
The data-sitekey attribute is present on most containers and identifies the site's account with the provider β useful for confirming a match rather than guessing from a class name alone.
3. A Practical Probe
import re
MARKERS = [
("reCAPTCHA", r'class="[^"]*g-recaptcha|www\.google\.com/recaptcha|grecaptcha'),
("hCaptcha", r'class="[^"]*h-captcha|hcaptcha\.com'),
("Turnstile", r'class="[^"]*cf-turnstile|challenges\.cloudflare\.com/turnstile'),
("Arkose/FunCaptcha",r'arkoselabs\.com|funcaptcha'),
("GeeTest", r'geetest_|gt\.js|initGeetest'),
("Friendly Captcha", r'frc-captcha|friendlycaptcha'),
("Tencent Captcha", r'captcha\.qcloud\.com|TencentCaptcha'),
]
def identify_captcha(html):
return [name for name, pat in MARKERS if re.search(pat, html, re.I)]
Run it against the raw HTML first. Where it finds nothing, repeat in a browser and check window globals β some CAPTCHAs are injected only after a risk assessment.
4. Absence Now Does Not Mean Absence Later
The most common mistake is concluding a site has no CAPTCHA because the first page load showed none.
Most modern providers are conditional: they appear when a risk score crosses a threshold. So the sequence to expect is a clean first request, then a challenge after N requests, or from a particular address, or on a particular action.
The practical consequence: probe repeatedly and from different addresses before concluding a site is ungated, and treat a rising challenge rate as the real measurement rather than a single observation.
5. Distinguish the Gate From the Content
Once identified, the more useful question is what the CAPTCHA guards:
- A login or signup form β the content behind it may be irrelevant to you.
- A search or listing action β the data path itself is gated.
- The whole site, on first visit β an edge-level challenge, not a form CAPTCHA.
- A specific high-value action β checkout, booking, ticket release.
Only the second and third genuinely block public data collection. The others frequently sit beside content that is reachable without them.
6. Turnstile Is a Special Case
Cloudflare Turnstile often runs invisibly, with no interaction required, as part of edge protection rather than as a form widget. Its presence therefore says less about whether you are blocked than a visible puzzle would β it may simply be assessing and passing you.
Identify it, but read it as bot management rather than as a wall.
7. What to Record
For each site, log the provider, where it appears, what triggers it, and the rate. That turns a one-off observation into a usable signal:
site, provider, trigger_path, appeared_after_n_requests, egress_country, observed_at
The appeared_after_n_requests column is the one that tells you whether the setup is being scored, and it is the field most people never capture.
8. Summary
Identify a CAPTCHA from its DOM container and data-sitekey, its script domain, its window global, and its response field name β the first two visible in raw HTML, the last two only after JavaScript runs.
Never conclude from one clean request that a site is ungated, because most providers are conditional on a risk score; probe repeatedly from different addresses, record what triggers the challenge and after how many requests, and distinguish a CAPTCHA guarding a form from one guarding the content you actually want.