Keduanya merupakan varian reCAPTCHA v2 yang menggunakan teknologi dasar yang sama. Versi kotak centang menampilkan "Saya bukan robot" dan mungkin menampilkan kisi-kisi gambar. Versi invisible terpicu secara otomatis pada tindakan pengguna (klik tombol, pengiriman formulir, atau pemuatan halaman) tanpa widget yang terlihat. Untuk solve CaptchaAI, satu-satunya perbedaan adalah menambahkan invisible=1 ke permintaan Anda — tetapi proses pengaturan token berbeda secara signifikan.
Perbandingan berdampingan
| Fitur | v2 Kotak centang | v2 Invisible |
|---|---|---|
| Widget yang terlihat | Ya — kotak centang "Saya bukan robot". | Tidak — disembunyikan dari pengguna |
| Mekanisme pemicu | Kotak centang klik pengguna | Klik tombol, pengiriman formulir, atau pemuatan halaman |
| Tantangan gambar | Ditampilkan saat Google mencurigai adanya bot | Munculan di pojok kanan bawah jika mencurigakan |
| Pengalaman pengguna | Gesekan sedang | Gesekan rendah/zero |
| Implementasi | Tambahkan div g-recaptcha ke halaman |
Tambahkan data-callback ke tombol atau grecaptcha.execute() |
| Format sitekey | Sama seperti invisible | Sama seperti kotak centang |
| bidang token | g-recaptcha-response |
g-recaptcha-response |
| Fungsi callback | Opsional | Hampir selalu diperlukan |
| metode CaptchaAI | method=userrecaptcha |
method=userrecaptcha + invisible=1 |
| Token seumur hidup | 120 detik | 120 detik |
| Selesaikan waktu | 10-30 detik | 10-25 detik |
Bagaimana masing-masing muncul di HTML
v2 Kotak centang
<!-- 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 -->
Pengguna melihat dan berinteraksi dengan kotak centang. Jika Google curiga, tantangan kisi gambar akan muncul sebaris.
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>
Tidak ada widget yang terlihat. reCAPTCHA aktif ketika pengguna memicu elemen tertentu atau ketika grecaptcha.execute() dipanggil.
Cara mendeteksi varian mana yang ada pada suatu halaman
Deteksi ular piton:
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://staging.example.com/qa-login")
print(result)
Deteksi 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;
}
Pemeriksaan konsol browser cepat:
const el = document.querySelector('[data-size="invisible"]');
console.log(el ? "Invisible reCAPTCHA" : "Checkbox reCAPTCHA");
| Sinyal deteksi | v2 Kotak centang | v2 Invisible |
|---|---|---|
data-size="invisible" |
Tidak hadir | Hadir |
| Kotak centang terlihat di halaman | Ya | Tidak |
grecaptcha.execute() menelepon |
Tidak (klik pengguna) | Ya (terprogram) |
| Tantang posisi popup | Sebaris, di bawah kotak centang | Sudut kanan bawah halaman |
Menyelesaikan dengan CaptchaAI
v2 Kotak centang
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
pengaturan token — perbedaan penting
v2 Kotak Centang: Bidang tersembunyi biasanya cukup
# 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: Callback hampir selalu diperlukan
# 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);
Perbedaan utama: Formulir kotak centang v2 sering kali berfungsi hanya dengan injeksi kolom tersembunyi karena klik pengguna pada kotak centang sudah mendaftarkan callback. ReCAPTCHA yang invisible tidak pernah memiliki klik tersebut — callback harus dipanggil secara eksplisit.
Pemecah universal untuk kedua varian
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://staging.example.com/qa-login")
print(f"Variant: {result['variant']}, Callback: {result['callback']}")
Pemecahan Masalah
| Masalah | Perbaikan kotak centang | Perbaikan yang invisible |
|---|---|---|
| Token tidak diterima | Suntikkan ke bidang g-recaptcha-response |
Suntikkan DAN panggil fungsi data-callback |
| Widget tidak ditemukan | Cari kelas .g-recaptcha |
Periksa data-size="invisible" atau panggilan render skrip |
| Formulir dikirimkan tetapi gagal | Periksa apakah callback diharapkan | Callback hampir selalu diperlukan — temukan dan telepon |
| Halaman dimuat ulang setelah injeksi | Validasi JavaScript gagal | Panggil callback before pemicu pengiriman otomatis formulir |
Pertanyaan Umum
Apakah reCAPTCHA yang invisible lebih sulit dipecahkan?
Tidak. Proses solve melalui CaptchaAI hampir sama. Menambahkan invisible=1 ke permintaan Anda adalah satu-satunya perubahan. Tantangan tambahannya ada di sisi injeksi: Anda harus menemukan dan menjalankan fungsi callback.
Apakah keduanya menggunakan format sitekey yang sama?
Ya. Format sitekeynya identik. Anda tidak dapat mengetahui variannya hanya dari sitekey — periksa data-size="invisible" di HTML.
Apakah reCAPTCHA yang invisible masih menampilkan tantangan gambar?
Ya. Saat Google mendeteksi perilaku mencurigakan, reCAPTCHA yang invisible menampilkan popup tantangan gambar di pojok kanan bawah halaman. Inilah mengapa Anda masih memerlukan CaptchaAI — versi yang invisible masih dapat menghadirkan tantangan.
Bisakah situs beralih antara kotak centang dan invisible?
Ya. Ini adalah perubahan konfigurasi di bagian akhir situs — sitekey yang sama, implementasi berbeda. Beberapa situs menggunakan kotak centang di desktop dan invisible di seluler. Selalu deteksi varian secara dinamis.
Mana yang lebih cepat diselesaikan?
Solve yang invisible biasanya sedikit lebih cepat (10-25 detik vs 10-30 detik) karena cenderung memicu lebih sedikit tantangan gambar. Namun perbedaannya kecil.
Panduan terkait
- Cara Mengatasi reCAPTCHA v2 Menggunakan API— tutorial kotak centang v2 lengkap
- Bagaimana reCAPTCHA Invisible Bekerja— penjelasan mekanisme tak kasat mata
- Cara Mengatasi reCAPTCHA Invisible Menggunakan API— tutorial solve tak kasat mata
- Kesalahan dan Perbaikan reCAPTCHA Invisible Umum— pemecahan masalah yang invisible
- Cara Mengatasi reCAPTCHA Invisible Menggunakan API
- Bagaimana reCAPTCHA Invisible Bekerja
- reCAPTCHA v2 vs v3 Dijelaskan