Comparatifs

reCAPTCHA v2 vs Invisible reCAPTCHA expliqué

Les deux sont des variantes de reCAPTCHA v2 utilisant la même technologie sous-jacente. La version checkbox affiche "Je ne suis pas un robot" et peut présenter des grilles d'images. La version invisible se déclenche automatiquement lors des actions de l'utilisateur (clic sur un bouton, soumission de formulaire ou chargement de page) sans widget visible. Pour la résolution de CaptchaAI, la seule différence est d'ajouter invisible=1 à votre demande, mais le processus d'injection de jetons diffère considérablement.


Comparaison côte à côte

Caractéristique v2 Case à cocher v2 invisible
Widget visible Oui — case à cocher « Je ne suis pas un robot » Non – masqué aux utilisateurs
Mécanisme de déclenchement L'utilisateur clique sur la case à cocher Clic sur un bouton, soumission de formulaire ou chargement de page
Défi d'image S'affiche lorsque Google soupçonne un bot Pop-up dans le coin inférieur droit en cas de suspicion
Expérience utilisateur Frottement modéré Faible friction/zero
Mise en œuvre Ajouter le div g-recaptcha à la page Ajoutez data-callback au bouton ou grecaptcha.execute()
Format de clé de site Identique à l'invisible Identique à la case à cocher
Champ de jeton g-recaptcha-response g-recaptcha-response
Fonction de rappel Facultatif Presque toujours requis
Méthode CaptchaAI method=userrecaptcha method=userrecaptcha + invisible=1
Durée de vie du jeton 120 secondes 120 secondes
Résoudre le temps 10-30 secondes 10-25 secondes

Comment chacun apparaît dans le HTML

v2 Case à cocher

<!-- 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 -->

L'utilisateur voit et interagit avec la case à cocher. Si Google est suspect, un défi de grille d'images apparaît en ligne.

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>

Aucun widget visible. reCAPTCHA s'active lorsque l'utilisateur déclenche l'élément spécifié ou lorsque grecaptcha.execute() est appelé.


Comment détecter quelle variante se trouve sur une page

Détection 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)

Détection 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;
}

Vérification rapide de la console du navigateur :

const el = document.querySelector('[data-size="invisible"]');
console.log(el ? "Invisible reCAPTCHA" : "Checkbox reCAPTCHA");
Signal de détection v2 Case à cocher v2 invisible
data-size="invisible" Pas présent Présent
Case à cocher visible sur la page Oui Non
grecaptcha.execute() a appelé Non (l'utilisateur clique) Oui (programmatique)
Position contextuelle du défi En ligne, case à cocher ci-dessous Coin inférieur droit de la page

Résolution avec CaptchaAI

v2 Case à cocher

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

Injection de jetons – la différence critique

Case à cocher v2 : Le champ masqué est généralement suffisant

# 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 : le rappel est presque toujours requis

# 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);

Différence clé : Les formulaires de case à cocher v2 fonctionnent souvent avec uniquement l'injection de champ caché, car le clic de l'utilisateur sur la case à cocher a déjà enregistré le rappel. Invisible reCAPTCHA n'a jamais ce clic : le rappel doit être appelé explicitement.


Solveur universel pour les deux variantes

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']}")

Dépannage

Problème Correction de la case à cocher Solution invisible
Jeton non accepté Injecter dans le champ g-recaptcha-response Injecter ET appeler la fonction data-callback
Widget introuvable Recherchez la classe .g-recaptcha Recherchez data-size="invisible" ou les appels de rendu de script
Le formulaire est soumis mais échoue Vérifiez si un rappel est attendu Un rappel est presque toujours nécessaire : trouvez-le et appelez-le
Rechargement de la page après injection La validation JavaScript a échoué Rappel d'appel avant les déclencheurs de soumission automatique du formulaire

FAQ

Le reCAPTCHA invisible est-il plus difficile à résoudre ?

Non. Le processus de résolution via CaptchaAI est presque identique. L'ajout de invisible=1 à votre demande est le seul changement. Le défi supplémentaire se situe du côté de l’injection : vous devez trouver et exécuter la fonction de rappel.

Les deux utilisent-ils le même format de clé de site ?

Oui. Le format de la clé de site est identique. Vous ne pouvez pas distinguer la variante à partir de la clé du site uniquement – ​​recherchez data-size="invisible" dans le code HTML.

Le reCAPTCHA invisible affiche-t-il toujours des problèmes d'image ?

Oui. Lorsque Google détecte un comportement suspect, invisible reCAPTCHA affiche une fenêtre contextuelle de défi d'image dans le coin inférieur droit de la page. C'est pourquoi vous avez toujours besoin de CaptchaAI : la version invisible peut toujours présenter des défis.

Un site peut-il basculer entre case à cocher et invisible ?

Oui. Il s'agit d'un changement de configuration du côté du site : même clé de site, implémentation différente. Certains sites utilisent une case à cocher sur ordinateur et invisible sur mobile. Détectez toujours la variante de manière dynamique.

Qu’est-ce qui est le plus rapide à résoudre ?

Les résolutions invisibles sont généralement légèrement plus rapides (10 à 25 secondes contre 10 à 30 secondes) car elles ont tendance à déclencher moins de défis d'image. Mais la différence est marginale.


Guides associés

Les commentaires sont désactivés pour cet article.