Checkbox oder unsichtbar – für das Lösen mit CaptchaAI macht das kaum einen Unterschied: Sie hängen lediglich invisible=1 an Ihre Anfrage an. Der eigentliche Aufwand steckt an einer anderen Stelle, nämlich darin, das gelöste Token sauber in die Seite zurückzuspielen. Denn beide sind Varianten von reCAPTCHA v2, teilen sich dieselbe Technik und denselben Sitekey. Die Checkbox-Variante zeigt das bekannte „Ich bin kein Roboter"-Feld und blendet bei Verdacht ein Bildraster ein. Die unsichtbare Variante läuft ohne sichtbares Widget und wird automatisch durch eine Nutzeraktion ausgelöst – einen Klick, ein Formular-Absenden oder das Laden der Seite. Dieser Artikel zeigt, wie Sie beide im HTML auseinanderhalten und jede zuverlässig verarbeiten.
So sieht jede reCAPTCHA-v2-Variante im HTML aus
v2-Checkbox
<!-- 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 Nutzer sieht die Checkbox und klickt sie an. Hält Google die Sitzung für verdächtig, erscheint direkt darunter ein Bildraster als zusätzliche Abfrage.
v2 Invisible
<!-- 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 erst aktiv, wenn der Nutzer das hinterlegte Element auslöst oder grecaptcha.execute() aufgerufen wird.
reCAPTCHA v2 Checkbox oder Invisible: der Unterschied auf einen Blick
Verhalten und Nutzererlebnis
| Merkmal | v2-Checkbox | v2 Invisible |
|---|---|---|
| Sichtbares Widget | Ja – „Ich bin kein Roboter"-Feld | Nein – für Nutzer unsichtbar |
| Auslöser | Nutzer klickt das Feld an | Klick, Formular-Absenden oder Seitenaufruf |
| Bild-Abfrage | Erscheint, wenn Google einen Bot vermutet | Popup unten rechts bei Verdacht |
| Nutzererlebnis | Spürbare Reibung | Kaum bis keine Reibung |
Einbindung und Lösung
| Merkmal | v2-Checkbox | v2 Invisible |
|---|---|---|
| Einbindung | g-recaptcha-div auf der Seite |
data-callback am Button oder grecaptcha.execute() |
| Sitekey-Format | Identisch mit Invisible | Identisch mit Checkbox |
| Token-Feld | g-recaptcha-response |
g-recaptcha-response |
| Callback | Optional | Fast immer Pflicht |
| CaptchaAI-Methode | method=userrecaptcha |
method=userrecaptcha + invisible=1 |
| Token-Lebensdauer | 120 Sekunden | 120 Sekunden |
| Lösungszeit | 10–30 Sekunden | 10–25 Sekunden |
Variante zuverlässig im Code erkennen
In der Praxis wissen Sie oft nicht im Voraus, welche Variante Sie erwartet – und viele DACH-Portale sind in den letzten Jahren stillschweigend von der sichtbaren Checkbox auf Invisible umgestiegen, vom Shopware-Login bis zum Registrierungsformular. Ermitteln Sie die Variante deshalb immer dynamisch aus dem HTML. Diese vier Signale trennen die Varianten:
| Erkennungssignal | v2-Checkbox | v2 Invisible |
|---|---|---|
data-size="invisible" |
Fehlt | Vorhanden |
| Sichtbare Checkbox auf der Seite | Ja | Nein |
grecaptcha.execute() wird aufgerufen |
Nein (Nutzerklick) | Ja (programmatisch) |
| Position des Challenge-Popups | Inline, unter der Checkbox | Unten rechts auf der Seite |
Erkennung mit Python
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)
Erkennung mit Node.js
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;
}
Schnellprüfung in der Browser-Konsole
const el = document.querySelector('[data-size="invisible"]');
console.log(el ? "Invisible reCAPTCHA" : "Checkbox reCAPTCHA");
Beide Varianten mit CaptchaAI lösen
Auf der API-Seite ist der Unterschied ein einziger Parameter. Sie senden die Aufgabe an in.php und fragen das Ergebnis von res.php ab – bei Invisible kommt lediglich invisible=1 hinzu.
v2-Checkbox
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 Invisible
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 einfügen – hier trennen sich die Varianten
v2-Checkbox: das versteckte Feld genügt meist
# 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 Invisible: der Callback ist Pflicht
# 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}");')
Dasselbe mit Puppeteer
// 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);
Der springende Punkt: Bei der Checkbox reicht oft das versteckte Feld allein, weil der Klick des Nutzers den Callback bereits registriert hat. Invisible reCAPTCHA kennt diesen Klick nie – hier müssen Sie den Callback selbst aufrufen, sonst wird ein technisch gültiges Token von der Seite ignoriert.
Fehlerbehebung
Token wird nicht akzeptiert
Checkbox: in g-recaptcha-response schreiben. Invisible: schreiben UND den data-callback aufrufen.
Widget nicht gefunden
Checkbox: nach .g-recaptcha suchen. Invisible: nach data-size="invisible" oder Skript-Render-Aufrufen.
Formular sendet, schlägt aber fehl
Checkbox: prüfen, ob ein Callback erwartet wird. Invisible: Callback finden und aufrufen.
Seite lädt nach dem Einfügen neu
Checkbox: JavaScript-Validierung fehlgeschlagen. Invisible: Callback aufrufen, bevor das Formular absendet.
Universeller Löser für beide Varianten
Wenn Sie beide Fälle über einen einzigen Codepfad abdecken wollen, erkennen Sie die Variante zur Laufzeit und setzen invisible=1 nur, wenn es nötig ist:
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']}")
Häufige Fragen
Kostet das Lösen von Invisible mehr als von der Checkbox?
Nein. CaptchaAI rechnet Thread-basiert ab, nicht pro Lösung: Jeder Plan enthält unbegrenzte Lösungen pro Thread, und es gibt keinen Aufpreis nach CAPTCHA-Typ. Ob Checkbox oder Invisible spielt für die Kosten also keine Rolle – der Tarif richtet sich allein nach der Zahl paralleler Threads, ab BASIC (15 $/Monat, 5 Threads).
Warum wird mein gültiges Token bei Invisible abgelehnt?
Weil das versteckte Feld allein nicht ausreicht. Bei Invisible fehlt der Nutzerklick, der sonst den Callback anstößt. Schreiben Sie das Token in g-recaptcha-response und rufen Sie zusätzlich die in data-callback hinterlegte Funktion auf – erst danach akzeptiert die Seite das Token.
Woran erkenne ich die Variante direkt im Browser?
Öffnen Sie die Konsole und prüfen Sie mit document.querySelector('[data-size="invisible"]'), ob ein unsichtbares Widget existiert. Fehlt es und ist stattdessen eine „Ich bin kein Roboter"-Checkbox sichtbar, handelt es sich um die Checkbox-Variante.
Kann eine Seite je nach Gerät zwischen beiden umschalten?
Ja. Es ist derselbe Sitekey mit unterschiedlicher Einbindung – manche Seiten zeigen am Desktop eine Checkbox und laufen mobil unsichtbar. Verlassen Sie sich nie auf eine feste Annahme, sondern erkennen Sie die Variante bei jedem Aufruf neu.
Brauche ich für Invisible einen anderen CaptchaAI-Endpunkt?
Nein. Sie nutzen denselben in.php/res.php-Ablauf und dieselbe Methode userrecaptcha. Der einzige Zusatz ist der Parameter invisible=1 in der Anfrage an in.php; alles Weitere bleibt identisch.
Verwandte Leitfäden
- reCAPTCHA v2 per API lösen
- Invisible reCAPTCHA per API lösen
- Invisible reCAPTCHA: Trigger sicher erkennen