Explainers

reCAPTCHA v2 Invisible: Deteksi Trigger dan Cara Solve

Skrip Anda mengirim form, server membalas "verifikasi gagal", dan di halaman tidak ada kotak centang apa pun? Kemungkinan besar itu reCAPTCHA v2 Invisible. Varian ini tidak menampilkan widget: ia menempel pada tombol submit, berjalan sendiri saat tombol diklik, dan hanya memunculkan tantangan gambar bila analisis risiko Google menilai trafiknya mencurigakan.

Tiga hal yang akan Anda dapatkan di sini:

  • cara memastikan sebuah halaman memakai Invisible, langsung dari browser console;
  • cara menemukan sitekey dan elemen pemicunya;
  • alur solve lewat API CaptchaAI dengan parameter invisible=1.

Jawaban singkat: cek data-size="invisible" atau .grecaptcha-badge di console. Kalau salah satunya ada, kirim sitekey ke in.php dengan invisible=1, lalu suntikkan token dan panggil callback-nya.


Kenapa Invisible lebih sulit dikenali daripada v2 biasa

reCAPTCHA v2 standar mengumumkan dirinya lewat kotak centang. Invisible tidak:

Karakteristik reCAPTCHA v2 standar reCAPTCHA v2 Invisible
Widget terlihat Ya (kotak centang) Tidak (hanya badge di sudut)
Interaksi pengguna Klik kotak centang Otomatis saat form dikirim
data-size normal atau compact invisible
Tantangan gambar Selalu mungkin muncul Hanya untuk trafik mencurigakan
Elemen DOM div .g-recaptcha div .g-recaptcha atau dipanggil lewat kode

Konsekuensi praktisnya untuk otomatisasi:

  • pada v2 standar, selector kotak centang memberi tahu Anda bahwa ada CAPTCHA;
  • pada Invisible, tidak ada yang gagal di sisi browser — form terkirim, token kosong, dan penolakan baru terjadi di server.

Empat cara memastikan halaman memakai reCAPTCHA Invisible

Jalankan pemeriksaan berikut di browser console sebelum menulis satu baris kode otomatisasi, berurutan dari yang paling cepat:

  1. atribut data-size pada widget;
  2. keberadaan badge reCAPTCHA;
  3. pemanggilan grecaptcha.execute() di skrip inline;
  4. parameter render= pada tag skrip.

Cek atribut data-size pada widget

// Browser console
const widgets = document.querySelectorAll('.g-recaptcha');
widgets.forEach((el, i) => {
  const size = el.getAttribute('data-size');
  const sitekey = el.getAttribute('data-sitekey');
  console.log(`Widget ${i}: size=${size}, sitekey=${sitekey}`);
  if (size === 'invisible') {
    console.log('  → This is Invisible reCAPTCHA');
  }
});

Kalau nilainya invisible, tidak perlu lanjut — Anda sudah mendapat jawabannya sekaligus sitekey-nya.

Cari badge reCAPTCHA di sudut halaman

Invisible tetap memuat badge kecil, meski banyak situs menyembunyikannya lewat CSS. Badge yang ada tetapi disembunyikan adalah petunjuk kuat.

const badge = document.querySelector('.grecaptcha-badge');
if (badge) {
  console.log('reCAPTCHA badge found — likely Invisible reCAPTCHA');
  console.log('Badge visibility:', getComputedStyle(badge).visibility);
}

Telusuri pemanggilan grecaptcha.execute di skrip halaman

Sebagian situs tidak memakai div .g-recaptcha sama sekali dan memanggil reCAPTCHA dari kode. Sitekey-nya biasanya ada di skrip inline:

// Look for grecaptcha.execute in page scripts
document.querySelectorAll('script:not([src])').forEach(s => {
  if (s.textContent.includes('grecaptcha.execute')) {
    console.log('Found grecaptcha.execute — Invisible reCAPTCHA');
    const match = s.textContent.match(/grecaptcha\.execute\s*\(\s*['"]?([^'",\s)]+)/);
    if (match) console.log('Sitekey:', match[1]);
  }
});

Periksa parameter render pada tag skrip

Cek ini tidak memisahkan Invisible dari v3 — keduanya memuat render=. Pakai untuk konfirmasi, lalu bedakan lewat ada-tidaknya parameter action.

document.querySelectorAll('script[src*="recaptcha"]').forEach(s => {
  if (s.src.includes('render=') && !s.src.includes('render=explicit')) {
    console.log('Invisible/v3 reCAPTCHA detected in script:', s.src);
  }
});

Kalau tiga cek pertama nihil tetapi tag skrip reCAPTCHA tetap dimuat, asumsikan pemanggilan terprogram dan telusuri bundle JavaScript-nya.


Menyelesaikan dengan API CaptchaAI

Alurnya sama dengan reCAPTCHA v2 biasa, plus satu parameter wajib invisible=1:

  1. kirim task ke in.php beserta googlekey, pageurl, dan invisible=1;
  2. simpan task ID dari respons;
  3. polling res.php sampai statusnya siap;
  4. suntikkan token ke halaman.

reCAPTCHA v2 Invisible termasuk tipe yang didukung CaptchaAI.

Python

import requests
import time

API_KEY = "YOUR_API_KEY"

# Submit with invisible flag
resp = requests.post("https://ocr.captchaai.com/in.php", data={
    "key": API_KEY,
    "method": "userrecaptcha",
    "googlekey": "6Le-SITEKEY",
    "pageurl": "https://staging.example.com/qa-login",
    "invisible": "1",  # critical for Invisible reCAPTCHA
    "json": "1",
}).json()

if resp["status"] != 1:
    raise Exception(f"Submit error: {resp['request']}")

task_id = resp["request"]
print(f"Submitted: {task_id}")

# Poll for result
for _ in range(24):
    time.sleep(5)
    result = requests.get("https://ocr.captchaai.com/res.php", params={
        "key": API_KEY, "action": "get", "id": task_id, "json": "1"
    }).json()

    if result["status"] == 1:
        print(f"Token: {result['request'][:50]}...")
        break
    if result["request"] != "CAPCHA_NOT_READY":
        raise Exception(f"Error: {result['request']}")

Jeda polling lima detik pada loop di atas aman untuk worker di AWS ap-southeast-1 (Singapura) maupun ap-southeast-3 (Jakarta). Yang perlu dijaga: jumlah task paralel tidak melebihi thread yang Anda miliki.

Node.js

const axios = require('axios');

const resp = await axios.post('https://ocr.captchaai.com/in.php', null, {
  params: {
    key: 'YOUR_API_KEY',
    method: 'userrecaptcha',
    googlekey: '6Le-SITEKEY',
    pageurl: 'https://staging.example.com/qa-login',
    invisible: 1,
    json: 1,
  }
});
const taskId = resp.data.request;
console.log(`Submitted: ${taskId}`);

Menyuntikkan token dan memicu callback

Token yang sudah diperoleh tidak otomatis membuat form lolos. Tuliskan token ke textarea[name="g-recaptcha-response"], lalu panggil fungsi callback yang terdaftar pada widget:

from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
driver.get("https://staging.example.com/qa-login")

# After solving, inject and trigger
driver.execute_script("""
    // Set the token
    document.querySelector('textarea[name="g-recaptcha-response"]').value = arguments[0];

    // Find and trigger the callback
    var widget = document.querySelector('.g-recaptcha');
    var callbackName = widget ? widget.getAttribute('data-callback') : null;

    if (callbackName && typeof window[callbackName] === 'function') {
        window[callbackName](arguments[0]);
    }
""", token)

# Submit the form
driver.find_element(By.CSS_SELECTOR, "form#login").submit()

Kalau situs tidak mendefinisikan data-callback, submit form biasa umumnya cukup — asalkan token sudah ada di textarea sebelum submit.


Menemukan elemen pemicu

Kalau langkah di atas tetap ditolak, penyebabnya biasanya di sisi pemicu. Invisible terikat pada sebuah aksi, dengan dua pola lazim:

  • tombol submit itu sendiri membawa kelas g-recaptcha;
  • pemicu dipasang lewat event listener di kode situs.

Pola pertama terlihat langsung di HTML:

<button class="g-recaptcha"
        data-sitekey="6Le-SITEKEY"
        data-callback="onSubmit"
        data-size="invisible">
  Submit
</button>

Pola kedua hanya terlihat di skrip:

// Site's code
document.getElementById('submit-btn').addEventListener('click', function() {
  grecaptcha.execute();
});

Untuk memetakan keduanya sekaligus:

// Find elements with g-recaptcha class that are buttons
document.querySelectorAll('button.g-recaptcha, input.g-recaptcha').forEach(el => {
  console.log('Trigger element:', el.tagName, el.textContent.trim());
  console.log('  data-sitekey:', el.getAttribute('data-sitekey'));
  console.log('  data-callback:', el.getAttribute('data-callback'));
});

Catat nilai data-callback. Melewatkan pemanggilan fungsi itu adalah penyebab paling umum form yang "terkirim tetapi ditolak".


Skenario nyata: pipeline QA yang mendadak gagal senyap

Sebuah agensi price monitoring di Bandung menjalankan pengecekan harian pada form login staging milik kliennya sendiri. Dua bulan skrip mulus, lalu sekitar 40% run berakhir dengan halaman login yang dimuat ulang tanpa pesan kesalahan. Dugaan pertama tim: jaringan.

Penyebabnya: klien mengganti reCAPTCHA v2 standar dengan varian Invisible. Widget hilang, selector lama tidak menemukan apa pun, dan skrip submit dengan token kosong. Satu baris document.querySelector('.grecaptcha-badge') di console menutup diagnosis.

Dua pelajaran operasionalnya:

  • Jadikan pemeriksaan badge sebagai assertion di awal setiap run. Badge muncul padahal alur Anda tidak mengharapkannya? Hentikan run dan kirim alert — lebih murah daripada membersihkan data kotor.
  • Perhitungkan lonjakan volume sejak awal. Harga CaptchaAI dihitung per thread — BASIC ($15/bulan, 5 thread) sampai VIP-3 ($7,500/bulan, 5.000 thread), solve tanpa batas per thread — jadi yang Anda bayar adalah konkurensi, bukan jumlah solve.

Catatan kepatuhan: jalankan otomatisasi hanya pada properti yang Anda miliki atau yang izinnya Anda kantongi tertulis, dan hindari data pribadi — sejalan dengan UU Pelindungan Data Pribadi (UU 27/2022).


Ketika hasilnya tetap tidak sesuai

Gejala Penyebab paling mungkin Yang harus dilakukan
Token ditolak server invisible=1 tidak ikut terkirim Tambahkan invisible: "1" pada permintaan ke in.php
Sitekey tidak ketemu Tidak ada div .g-recaptcha Telusuri pemanggilan grecaptcha.render() atau grecaptcha.execute() di skrip
Form terkirim tetapi gagal Callback tidak pernah dipanggil Panggil fungsi pada data-callback setelah token disuntikkan
Tidak menemukan jejak CAPTCHA sama sekali Hanya aktif untuk trafik mencurigakan Cek elemen grecaptcha-badge dan tag skrip reCAPTCHA
Respons CAPCHA_NOT_READY terus-menerus Jeda polling terlalu rapat atau task ID salah Pertahankan jeda 5 detik dan pastikan task ID berasal dari respons submit

Pertanyaan Umum

Bagaimana membedakan reCAPTCHA v2 Invisible dari v3 di halaman yang sama?

Lihat dua penanda:

  • grecaptcha.execute() tanpa parameter action menandakan v2 Invisible; v3 selalu menyertakan objek berisi action;
  • URL skrip v3 memuat render=SITEKEY, v2 Invisible tidak.

Apakah proses solve bisa berjalan tanpa membuka browser?

Bisa untuk bagian solve-nya: CaptchaAI hanya perlu sitekey dan URL halaman. Browser tetap dibutuhkan untuk menyuntikkan token dan memicu callback di halaman sesungguhnya.

Berapa lama biasanya satu solve reCAPTCHA v2 Invisible selesai?

Bervariasi menurut beban dan kondisi jaringan. Pola polling lima detik dengan batas sekitar dua menit seperti contoh Python di atas adalah titik awal yang wajar — sesuaikan dari pengukuran Anda sendiri.

Berapa thread yang saya butuhkan untuk pekerjaan seperti ini?

Hitung dari jumlah CAPTCHA yang berjalan bersamaan, bukan total hariannya. Satu thread menangani satu solve aktif dan langsung bebas begitu selesai. Untuk satu skrip scraping tunggal, BASIC ($15/bulan, 5 thread) umumnya sudah lega.

Bagaimana kalau situs target pindah ke hCaptcha?

hCaptcha tidak didukung, begitu pula FunCaptcha (Arkose Labs); GeeTest v4 masih berstatus segera hadir. Yang didukung:

  • seluruh keluarga reCAPTCHA v2 dan v3;
  • Cloudflare Turnstile dan Cloudflare Challenge;
  • GeeTest v3, serta CAPTCHA gambar dan grid;
  • CaptchaFox (beta), Friendly Captcha (beta), dan Lemin (beta).

Mulai selesaikan reCAPTCHA v2 Invisible sekarang

Ambil API key Anda di captchaai.com, lalu jalankan contoh Python di atas pada halaman staging milik Anda sendiri: cek badge dulu, baru kirim task dengan invisible=1.


Panduan terkait

Komentar dinonaktifkan untuk artikel ini.