Bei beiden handelt es sich um reCAPTCHA v2-Varianten, die dieselbe zugrunde liegende Technologie verwenden. Die Checkbox-Version zeigt „Ich bin kein Roboter“ und kann Bildraster enthalten. Die unsichtbare Version wird automatisch bei Benutzeraktionen (Schaltflächenklick, Senden eines Formulars oder Laden der Seite) ohne sichtbares Widget ausgelöst. Bei der CaptchaAI-Lösung besteht der einzige Unterschied darin, Ihrer Anfrage invisible=1 hinzuzufügen – der Token-Injection-Prozess unterscheidet sich jedoch erheblich.
Direkter Vergleich
| Funktion | v2-Kontrollkästchen | v2 Unsichtbar |
|---|---|---|
| Sichtbares Widget | Ja – Kontrollkästchen „Ich bin kein Roboter“. | Nein – für Benutzer verborgen |
| Auslösemechanismus | Der Benutzer klickt auf das Kontrollkästchen | Klicken Sie auf eine Schaltfläche, senden Sie ein Formular oder laden Sie eine Seite |
| Image-Herausforderung | Wird angezeigt, wenn Google einen Bot vermutet | Popup in der unteren rechten Ecke, wenn ein Verdacht besteht |
| Benutzererfahrung | Mäßige Reibung | Geringe Reibung |
| Umsetzung | g-recaptcha div zur Seite hinzufügen |
Fügen Sie data-callback zur Schaltfläche oder grecaptcha.execute() hinzu |
| Sitekey-Format | Dasselbe wie unsichtbar | Identisch mit Kontrollkästchen |
| Token-Feld | g-recaptcha-response |
g-recaptcha-response |
| Rückruffunktion | Optional | Fast immer erforderlich |
| CaptchaAI-Methode | method=userrecaptcha |
method=userrecaptcha + invisible=1 |
| Token-Lebensdauer | 120 Sekunden | 120 Sekunden |
| Zeit lösen | 10-30 Sekunden | 10-25 Sekunden |
Wie jedes im HTML angezeigt wird
v2-Kontrollkästchen
<!-- Standard checkbox widget -->
<div class="g-recaptcha"
data-sitekey="6Le-wvkSAAAAAPBMRTvw..."
data-callback="onSubmit">
</div>
<!-- Widget renders as: -->
<!-- [✓] I'm not a robot reCAPTCHA logo -->
Der Benutzer sieht das Kontrollkästchen und interagiert mit ihm. Wenn Google misstrauisch ist, wird inline eine Bildraster-Herausforderung angezeigt.
v2 Unsichtbar
<!-- Pattern 1: Invisible widget on a button -->
<button class="g-recaptcha"
data-sitekey="6Le-wvkSAAAAAPBMRTvw..."
data-callback="onSubmit"
data-size="invisible">
Submit
</button>
<!-- Pattern 2: Invisible div (programmatic trigger) -->
<div class="g-recaptcha"
data-sitekey="6Le-wvkSAAAAAPBMRTvw..."
data-size="invisible"
data-callback="onSubmit">
</div>
<!-- Pattern 3: Programmatic render -->
<script>
grecaptcha.render('submit-btn', {
sitekey: '6Le-wvkSAAAAAPBMRTvw...',
callback: onSubmit,
size: 'invisible'
});
</script>
Kein sichtbares Widget. reCAPTCHA wird aktiviert, wenn der Benutzer das angegebene Element auslöst oder wenn grecaptcha.execute() aufgerufen wird.
So erkennen Sie, welche Variante sich auf einer Seite befindet
Python-Erkennung:
import requests
from bs4 import BeautifulSoup
import re
def detect_recaptcha_variant(url):
resp = requests.get(url)
soup = BeautifulSoup(resp.text, "html.parser")
# Check for invisible indicators
invisible_widget = soup.find(attrs={"data-size": "invisible", "class": "g-recaptcha"})
if invisible_widget:
return {
"variant": "invisible",
"sitekey": invisible_widget.get("data-sitekey"),
"callback": invisible_widget.get("data-callback")
}
# Check for programmatic invisible in scripts
for script in soup.find_all("script"):
if script.string and "invisible" in str(script.string):
key_match = re.search(r"sitekey['\"]?\s*[:=]\s*['\"]([^'\"]+)", script.string)
if key_match:
return {
"variant": "invisible-programmatic",
"sitekey": key_match.group(1),
"callback": "check grecaptcha.render() call"
}
# Check for standard checkbox
checkbox_widget = soup.find(class_="g-recaptcha")
if checkbox_widget:
return {
"variant": "checkbox",
"sitekey": checkbox_widget.get("data-sitekey"),
"callback": checkbox_widget.get("data-callback")
}
return None
result = detect_recaptcha_variant("https://example.com/login")
print(result)
Node.js-Erkennung:
const axios = require("axios");
const cheerio = require("cheerio");
async function detectRecaptchaVariant(url) {
const { data } = await axios.get(url);
const $ = cheerio.load(data);
// Check for invisible
const invisible = $(".g-recaptcha[data-size='invisible']");
if (invisible.length) {
return {
variant: "invisible",
sitekey: invisible.attr("data-sitekey"),
callback: invisible.attr("data-callback"),
};
}
// Check scripts for programmatic invisible
const scripts = $("script")
.map((_, el) => $(el).html())
.get()
.join("\n");
if (scripts.includes("invisible")) {
const keyMatch = scripts.match(/sitekey['"]?\s*[:=]\s*['"]([^'"]+)/);
if (keyMatch) {
return {
variant: "invisible-programmatic",
sitekey: keyMatch[1],
callback: "check render call",
};
}
}
// Check for standard checkbox
const checkbox = $(".g-recaptcha");
if (checkbox.length) {
return {
variant: "checkbox",
sitekey: checkbox.attr("data-sitekey"),
callback: checkbox.attr("data-callback"),
};
}
return null;
}
Schnelle Überprüfung der Browserkonsole:
const el = document.querySelector('[data-size="invisible"]');
console.log(el ? "Invisible reCAPTCHA" : "Checkbox reCAPTCHA");
| Erkennungssignal | v2-Kontrollkästchen | v2 Unsichtbar |
|---|---|---|
data-size="invisible" |
Nicht vorhanden | Anwesend |
| Sichtbares Kontrollkästchen auf der Seite | Ja | Nein |
grecaptcha.execute() aufgerufen |
Nein (Benutzerklicks) | Ja (programmatisch) |
| Popup-Position der Herausforderung | Inline, unten Kontrollkästchen | Unten rechts auf der Seite |
Lösung mit CaptchaAI
v2-Kontrollkästchen
import requests
import time
resp = requests.get("https://ocr.captchaai.com/in.php", params={
"key": "YOUR_API_KEY",
"method": "userrecaptcha",
"googlekey": "6Le-wvkSAAAA...",
"pageurl": "https://example.com/form"
})
task_id = resp.text.split("|")[1]
for _ in range(60):
time.sleep(5)
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": "YOUR_API_KEY", "action": "get", "id": task_id
})
if result.text.startswith("OK|"):
token = result.text.split("|")[1]
break
v2 Unsichtbar
import requests
import time
resp = requests.get("https://ocr.captchaai.com/in.php", params={
"key": "YOUR_API_KEY",
"method": "userrecaptcha",
"googlekey": "6Le-wvkSAAAA...",
"pageurl": "https://example.com/form",
"invisible": 1 # Only parameter difference
})
task_id = resp.text.split("|")[1]
for _ in range(60):
time.sleep(5)
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": "YOUR_API_KEY", "action": "get", "id": task_id
})
if result.text.startswith("OK|"):
token = result.text.split("|")[1]
break
Token-Injection – der entscheidende Unterschied
v2-Kontrollkästchen: Verstecktes Feld reicht normalerweise aus
# Selenium — inject into hidden field
driver.execute_script(
f'document.getElementById("g-recaptcha-response").value = "{token}";'
)
# If the page uses a callback, also call it
callback = driver.find_element("css selector", ".g-recaptcha").get_attribute("data-callback")
if callback:
driver.execute_script(f'{callback}("{token}");')
v2 Unsichtbar: Rückruf ist fast immer erforderlich
# Selenium — inject AND call the callback
driver.execute_script(
f'document.getElementById("g-recaptcha-response").value = "{token}";'
)
# CRITICAL: Invisible reCAPTCHA almost always requires calling the callback
callback_name = driver.find_element(
"css selector", ".g-recaptcha[data-size='invisible']"
).get_attribute("data-callback")
driver.execute_script(f'{callback_name}("{token}");')
// Puppeteer — invisible callback injection
await page.evaluate((tok) => {
// Set the hidden field
document.getElementById("g-recaptcha-response").value = tok;
// Find and call the callback function
const widget = document.querySelector("[data-size='invisible']");
const cbName = widget?.getAttribute("data-callback");
if (cbName && typeof window[cbName] === "function") {
window[cbName](tok);
}
}, token);
Hauptunterschied: Kontrollkästchenformulare der Version 2 funktionieren häufig nur mit der Eingabe versteckter Felder, da der Rückruf durch den Klick des Benutzers auf das Kontrollkästchen bereits registriert wurde. Unsichtbares reCAPTCHA hat nie diesen Klick – der Rückruf muss explizit aufgerufen werden.
Universeller Löser für beide Varianten
import requests
import time
from bs4 import BeautifulSoup
class RecaptchaV2UniversalSolver:
def __init__(self, api_key):
self.api_key = api_key
def detect_and_solve(self, page_url, page_html=None):
if not page_html:
page_html = requests.get(page_url).text
soup = BeautifulSoup(page_html, "html.parser")
# Detect variant
invisible = soup.find(attrs={"data-size": "invisible", "class": "g-recaptcha"})
widget = invisible or soup.find(class_="g-recaptcha")
if not widget:
raise Exception("No reCAPTCHA widget found")
sitekey = widget.get("data-sitekey")
is_invisible = invisible is not None
callback = widget.get("data-callback")
params = {
"key": self.api_key,
"method": "userrecaptcha",
"googlekey": sitekey,
"pageurl": page_url
}
if is_invisible:
params["invisible"] = 1
resp = requests.get("https://ocr.captchaai.com/in.php", params=params)
if not resp.text.startswith("OK|"):
raise Exception(f"Submit failed: {resp.text}")
task_id = resp.text.split("|")[1]
for _ in range(60):
time.sleep(5)
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": self.api_key, "action": "get", "id": task_id
})
if result.text.startswith("OK|"):
return {
"token": result.text.split("|")[1],
"variant": "invisible" if is_invisible else "checkbox",
"callback": callback,
"sitekey": sitekey
}
if result.text != "CAPCHA_NOT_READY":
raise Exception(f"Solve error: {result.text}")
raise Exception("Timed out")
# Usage
solver = RecaptchaV2UniversalSolver("YOUR_API_KEY")
result = solver.detect_and_solve("https://example.com/login")
print(f"Variant: {result['variant']}, Callback: {result['callback']}")
Fehlerbehebung
| Problem | Checkbox-Korrektur | Unsichtbare Lösung |
|---|---|---|
| Token nicht akzeptiert | In das Feld g-recaptcha-response einfügen |
Injizieren UND die Funktion data-callback aufrufen |
| Widget nicht gefunden | Suchen Sie nach der Klasse .g-recaptcha |
Suchen Sie nach data-size="invisible"- oder Skript-Renderaufrufen |
| Das Formular wird gesendet, schlägt jedoch fehl | Prüfen Sie, ob ein Rückruf erwartet wird | Ein Rückruf ist fast immer erforderlich – suchen Sie ihn und rufen Sie ihn an |
| Die Seite wird nach der Injektion neu geladen | Die JavaScript-Validierung ist fehlgeschlagen | Rufen Sie einen Rückruf auf, bevor die automatische Übermittlung des Formulars ausgelöst wird |
FAQ
Ist unsichtbares reCAPTCHA schwieriger zu lösen?
Nein. Der Lösungsprozess durch CaptchaAI ist nahezu identisch. Das Hinzufügen von invisible=1 zu Ihrer Anfrage ist die einzige Änderung. Die zusätzliche Herausforderung liegt auf der Injektionsseite: Sie müssen die Callback-Funktion finden und ausführen.
Verwenden beide das gleiche Sitekey-Format?
Ja. Das Sitekey-Format ist identisch. Sie können die Variante nicht allein anhand des Sitekeys erkennen – suchen Sie im HTML nach data-size="invisible".
Zeigt unsichtbares reCAPTCHA immer noch Bildherausforderungen an?
Ja. Wenn Google verdächtiges Verhalten erkennt, zeigt unsichtbares reCAPTCHA in der unteren rechten Ecke der Seite ein Bild-Challenge-Popup an. Aus diesem Grund benötigen Sie immer noch CaptchaAI – die unsichtbare Version kann immer noch Herausforderungen mit sich bringen.
Kann eine Site zwischen Kontrollkästchen und unsichtbar wechseln?
Ja. Dies ist eine Konfigurationsänderung seitens der Site – gleicher Sitekey, unterschiedliche Implementierung. Einige Websites verwenden ein Kontrollkästchen auf dem Desktop und sind auf Mobilgeräten unsichtbar. Erkennen Sie die Variante immer dynamisch.
Was ist schneller zu lösen?
Unsichtbare Lösungen sind in der Regel etwas schneller (10–25 Sekunden gegenüber 10–30 Sekunden), da sie tendenziell weniger Bildherausforderungen auslösen. Aber der Unterschied ist marginal.
Verwandte Leitfäden
- So lösen Sie reCAPTCHA v2 per API
- So lösen Sie reCAPTCHA Invisible per API
- reCAPTCHA v2 Invisible: Triggererkennung