Сравнения

Объяснение reCAPTCHA v2 и невидимой reCAPTCHA

Оба являются вариантами reCAPTCHA v2, использующими одну и ту же базовую технологию. Версия с флажком показывает «Я не робот» и может отображать сетки изображений. Невидимая версия срабатывает автоматически при действиях пользователя (нажатие кнопки, отправка формы или загрузка страницы) без видимого виджета. Единственная разница для решения CaptchaAI — это добавление invisible=1 к вашему запросу, но процесс передача токена во внутренний QA endpoint существенно отличается.


Параллельное сравнение

Особенность Флажок v2 v2 Невидимый
Видимый виджет Да — флажок «Я не робот» Нет — скрыто от пользователей
Спусковой механизм Пользователь нажимает флажок Нажатие кнопки, отправка формы или загрузка страницы
Задача изображения Отображается, когда Google подозревает бота Всплывающее окно в правом нижнем углу при подозрении
Пользовательский опыт Умеренное трение Низкое трение/zero
Выполнение Добавить div g-recaptcha на страницу Добавьте data-callback к кнопке или grecaptcha.execute().
Формат ключа сайта То же, что невидимка То же, что флажок
Поле токена g-recaptcha-response g-recaptcha-response
Функция обратного вызова Необязательный Почти всегда требуется
Метод CaptchaAI method=userrecaptcha method=userrecaptcha + invisible=1
Срок действия токена 120 секунд 120 секунд
Решить время 10-30 секунд 10–25 секунд

Как каждый из них отображается в HTML

Флажок v2

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

Пользователь видит флажок и взаимодействует с ним. Если у Google возникнут подозрения, в строке появится запрос на сетку изображений.

v2 Невидимый

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

Нет видимого виджета. reCAPTCHA активируется, когда пользователь запускает указанный элемент или когда вызывается grecaptcha.execute().


Как определить, какой вариант находится на странице

Обнаружение 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://https://staging.example.com/qa-login")
print(result)

Обнаружение 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;
}

Быстрая проверка консоли браузера:

const el = document.querySelector('[data-size="invisible"]');
console.log(el ? "Invisible reCAPTCHA" : "Checkbox reCAPTCHA");
Сигнал обнаружения Флажок v2 v2 Невидимый
data-size="invisible" Нет Подарок
Видимый флажок на странице Да Нет
grecaptcha.execute() позвонил Нет (пользователь нажимает) Да (программный)
Позиция всплывающего окна вызова Встроенное, под флажком Правый нижний угол страницы

Решение с помощью CaptchaAI

Флажок v2

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 Невидимый

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

передача токена во внутренний QA endpoint — критическая разница

Флажок v2: обычно достаточно скрытого поля.

# 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: обратный вызов требуется почти всегда.

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

Ключевое отличие: Формы флажков версии 2 часто работают только с внедрением скрытых полей, поскольку щелчок пользователя по флажку уже зарегистрировал обратный вызов. В невидимой reCAPTCHA такого щелчка никогда не происходит — обратный вызов должен вызываться явно.


Универсальный решатель для обоих вариантов

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://https://staging.example.com/qa-login")
print(f"Variant: {result['variant']}, Callback: {result['callback']}")

Поиск неисправностей

Проблема Исправление флажка Невидимое исправление
Токен не принят Внедрить в поле g-recaptcha-response Внедрить И вызвать функцию data-callback
Виджет не найден Найдите класс .g-recaptcha. Проверьте наличие data-size="invisible" или вызовов рендеринга сценария.
Форма отправляется, но не получается Проверьте, ожидается ли обратный звонок Обратный звонок требуется практически всегда — найдите и позвоните
Страница перезагружается после инъекции Проверка JavaScript не удалась Вызов обратного вызова перед формой триггеров автоматической отправки

Часто задаваемые вопросы

Сложнее ли решить невидимую reCAPTCHA?

Нет. Процесс решения с помощью CaptchaAI практически идентичен. Единственное изменение — добавление invisible=1 к вашему запросу. Дополнительная задача связана с внедрением: вы должны найти и выполнить функцию обратного вызова.

Оба используют один и тот же формат sitekey?

Да. Формат sitekey идентичен. Вы не можете определить вариант только по ключу сайта — проверьте наличие data-size="invisible" в HTML.

Невидимая reCAPTCHA по-прежнему показывает проблемы с изображением?

Да. Когда Google обнаруживает подозрительное поведение, невидимая reCAPTCHA отображает всплывающее окно с изображением в правом нижнем углу страницы. Вот почему вам все еще нужен CaptchaAI — невидимая версия все еще может представлять проблемы.

Может ли сайт переключаться между флажком и невидимостью?

Да. Это изменение конфигурации на стороне сайта — тот же ключ сайта, другая реализация. Некоторые сайты используют флажок на рабочем столе и невидим на мобильном устройстве. Всегда обнаруживайте вариант динамически.

Что быстрее решить?

Невидимые решения обычно выполняются немного быстрее (10–25 секунд против 10–30 секунд), поскольку они, как правило, вызывают меньше проблем с изображением. Но разница незначительна.


Связанные руководства

Комментарии для этой статьи отключены.