Kalau solve reCAPTCHA di halaman Google Search terus gagal padahal sitekey dan pageurl sudah benar, tersangka utamanya satu: parameter data-s yang tertinggal. data-s adalah token sesi yang wajib dikirim bersama permintaan solve pada properti Google — tanpa parameter ini, token yang dihasilkan ditolak dan solve gagal diam-diam. Artikel ini membahas apa itu data-s, di mana ia muncul, cara mengekstraknya, dan cara meneruskannya ke CaptchaAI.
Kapan data-s wajib disertakan
Tiga hal untuk diingat:
data-shanya muncul di properti milik Google — Google Search, YouTube, Google Play.- Jika atributnya ada di widget, wajib dikirim; jika tidak ada, jangan dikirim.
- Nilainya sekali pakai dan berubah setiap kali halaman dimuat.
Apa itu parameter data-s reCAPTCHA?
data-s adalah token sesi buatan server yang ditanam di HTML widget reCAPTCHA. Ia mengikat satu tantangan CAPTCHA ke satu sesi server, sehingga token hasil solve tidak bisa dipakai ulang — mirip nonce sekali pakai yang berbeda tiap pemuatan halaman.
Di mana data-s muncul di HTML
<!-- reCAPTCHA widget with data-s parameter -->
<div class="g-recaptcha"
data-sitekey="6LcR_RsTAAAAAN_r0GEkGBfq3L7KmU5JbPHJtwNp"
data-s="AB2grfE8_kyMp3XYRuJo5c..."
data-callback="onCaptchaSolved">
</div>
Atributnya duduk berdampingan dengan data-sitekey pada elemen <div>. Kalau tidak ada, halaman itu memang tidak memakainya.
Karakteristik data-s
| Properti | Nilai |
|---|---|
| Format | String berkode Base64, 200-500 karakter |
| Masa berlaku | Sekali pakai, terikat pada pemuatan halaman saat ini |
| Cakupan | Khusus sesi, tidak bisa dipakai ulang antar-pemuatan halaman |
| Wajib | Ya, jika ada — solve gagal tanpanya |
| Penyegaran | Nilai baru di setiap pemuatan/refresh halaman |
Cara kerja data-s secara teknis
Alur berikut menjelaskan mengapa token bisa ditolak walau challenge tampak terpecahkan:
User triggers CAPTCHA (e.g., Google flags unusual search traffic)
↓
Google serves a CAPTCHA page with:
- data-sitekey (site key, same for all Google search CAPTCHAs)
- data-s (session token, unique per page load)
↓
reCAPTCHA widget initializes with both parameters
↓
Challenge completion generates a g-recaptcha-response token
↓
Token is submitted alongside the session reference
↓
Google validates token + session binding
↓
If data-s was not used during solving: "invalid-input-response" or silent failure
Singkatnya, data-s mengikat tantangan ke sesi server. Solver harus memakai nilai itu saat membangun token; jika dilewati, validasi Google gagal meski challenge terpecahkan secara visual.
Kapan data-s muncul (dan kapan bisa diabaikan)
data-s TIDAK muncul di sebagian besar integrasi reCAPTCHA. Sebarannya hampir eksklusif di properti Google:
| Situs | Kehadiran | Catatan |
|---|---|---|
| Google Search (halaman sorry/unusual traffic) | Selalu | Wajib untuk solve CAPTCHA Google Search |
| YouTube | Kadang | Muncul pada alur verifikasi tertentu |
| Google Play | Kadang | Verifikasi daftar aplikasi |
| Google Forms | Jarang | Implementasi terbatas |
| Situs pihak ketiga dengan reCAPTCHA | Hampir tidak pernah | Integrasi standar tidak memakai data-s |
Contoh dari komunitas scraping lepas Indonesia: tim yang memantau halaman hasil Google dari region ap-southeast-3 (Jakarta) akan menemui halaman "unusual traffic" setelah ratusan permintaan — di situlah data-s muncul. Bila target Anda bukan properti Google, data-s praktis tidak relevan.
Mengekstrak data-s dari halaman target
Langkahnya selalu sama: ambil HTML halaman, temukan widget reCAPTCHA, lalu baca atribut data-s bila ada.
Ekstraksi dengan Python
Untuk halaman statis, requests dan BeautifulSoup sudah cukup:
import requests
from bs4 import BeautifulSoup
import re
def extract_recaptcha_params(url):
"""Extract reCAPTCHA parameters including data-s from a page."""
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/120.0.0.0 Safari/537.36",
}
response = requests.get(url, headers=headers, timeout=15)
soup = BeautifulSoup(response.text, "html.parser")
# Find reCAPTCHA widget div
widget = soup.find("div", class_="g-recaptcha")
if not widget:
# Try finding by data-sitekey attribute
widget = soup.find(attrs={"data-sitekey": True})
if not widget:
return {"error": "No reCAPTCHA widget found"}
params = {
"sitekey": widget.get("data-sitekey"),
"data_s": widget.get("data-s"),
"callback": widget.get("data-callback"),
"size": widget.get("data-size"),
"has_data_s": widget.get("data-s") is not None,
}
return params
# Example: Google "unusual traffic" page
params = extract_recaptcha_params("https://www.google.com/sorry/index")
print(params)
# {
# "sitekey": "6LfwuyUT...",
# "data_s": "AB2grfE8_kyMp3...",
# "has_data_s": True
# }
Ekstraksi dengan Node.js
Pola yang sama di Node.js memakai axios dan cheerio:
const axios = require("axios");
const cheerio = require("cheerio");
async function extractRecaptchaParams(url) {
const { data: html } = await axios.get(url, {
headers: {
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) " +
"AppleWebKit/537.36 (KHTML, like Gecko) " +
"Chrome/120.0.0.0 Safari/537.36",
},
timeout: 15000,
});
const $ = cheerio.load(html);
const widget = $(".g-recaptcha, [data-sitekey]").first();
if (widget.length === 0) {
return { error: "No reCAPTCHA widget found" };
}
return {
sitekey: widget.attr("data-sitekey"),
dataS: widget.attr("data-s") || null,
callback: widget.attr("data-callback") || null,
hasDataS: !!widget.attr("data-s"),
};
}
extractRecaptchaParams("https://www.google.com/sorry/index")
.then(console.log);
Ekstraksi dengan Selenium (untuk halaman dinamis)
Kalau widget baru muncul setelah JavaScript berjalan, pakai browser sungguhan lewat Selenium:
from selenium import webdriver
from selenium.webdriver.common.by import By
def extract_data_s_selenium(driver, url):
"""Extract data-s from a dynamically loaded reCAPTCHA page."""
driver.get(url)
# Wait for reCAPTCHA widget to load
import time
time.sleep(3)
try:
widget = driver.find_element(By.CSS_SELECTOR, ".g-recaptcha, [data-sitekey]")
return {
"sitekey": widget.get_attribute("data-sitekey"),
"data_s": widget.get_attribute("data-s"),
}
except Exception:
return {"error": "Widget not found"}
Ekstrak data-s sedekat mungkin dengan waktu kirim; nilai lama cepat basi.
Menyelesaikan reCAPTCHA dengan data-s di CaptchaAI
Setelah data-s di tangan, kirim sebagai field data-s ke in.php. Alurnya tetap empat langkah:
- Kirim task ke
in.phpbesertadata-s. - Simpan task ID dari respons.
- Polling
res.phpsampai status siap. - Pakai token
g-recaptcha-responsedi form target.
Python
import requests
import time
API_KEY = "YOUR_API_KEY"
# Step 1: Extract parameters from the CAPTCHA page
sitekey = "6LfwuyUTAAAAAOAmoS0fdqijC2PbbdH4kjq62Y1b"
data_s = "AB2grfE8_kyMp3XYRuJo5c..." # Extracted from data-s attribute
page_url = "https://www.google.com/sorry/index?continue=..."
# Step 2: Submit to CaptchaAI WITH data-s
submit = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY,
"method": "userrecaptcha",
"googlekey": sitekey,
"pageurl": page_url,
"data-s": data_s, # Include data-s parameter
"json": 1,
})
task_id = submit.json()["request"]
# Step 3: Poll for result
for _ in range(60):
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.get("status") == 1:
token = result["request"]
print(f"Token: {token[:60]}...")
# Submit this token to the Google CAPTCHA form
break
Node.js
const axios = require("axios");
async function solveWithDataS(sitekey, dataS, pageUrl) {
const API_KEY = "YOUR_API_KEY";
// Submit with data-s
const { data: submit } = await axios.post(
"https://ocr.captchaai.com/in.php",
new URLSearchParams({
key: API_KEY,
method: "userrecaptcha",
googlekey: sitekey,
pageurl: pageUrl,
"data-s": dataS,
json: 1,
})
);
const taskId = submit.request;
// Poll
for (let i = 0; i < 60; i++) {
await new Promise((r) => setTimeout(r, 5000));
const { data: result } = await axios.get(
"https://ocr.captchaai.com/res.php",
{
params: {
key: API_KEY,
action: "get",
id: taskId,
json: 1,
},
}
);
if (result.status === 1) {
return result.request;
}
}
throw new Error("Timeout");
}
Token g-recaptcha-response yang dikembalikan lalu ditempelkan ke form CAPTCHA target. Karena CaptchaAI menagih per thread, bukan per solve, retry akibat data-s basi tidak menambah biaya per permintaan — paket BASIC ($15/bulan, 5 thread) memberi solve tak terbatas per thread.
Helper ekstraksi data-s yang bisa dipakai ulang
Daripada menyalin logika yang sama di setiap skrip, bungkus dalam satu utilitas yang menangani halaman dengan maupun tanpa data-s:
import requests
from bs4 import BeautifulSoup
class RecaptchaExtractor:
"""Extract reCAPTCHA parameters from any page."""
def __init__(self, url, session=None):
self.url = url
self.session = session or requests.Session()
self.params = None
def extract(self):
"""Extract sitekey, data-s, and other parameters."""
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/120.0.0.0 Safari/537.36",
}
response = self.session.get(self.url, headers=headers, timeout=15)
soup = BeautifulSoup(response.text, "html.parser")
widget = soup.find(attrs={"data-sitekey": True})
if not widget:
raise ValueError("No reCAPTCHA widget found on page")
self.params = {
"sitekey": widget["data-sitekey"],
"pageurl": self.url,
}
# Include data-s only if present
data_s = widget.get("data-s")
if data_s:
self.params["data-s"] = data_s
return self.params
def build_solver_payload(self, api_key):
"""Build CaptchaAI submission payload with correct parameters."""
if not self.params:
self.extract()
payload = {
"key": api_key,
"method": "userrecaptcha",
"googlekey": self.params["sitekey"],
"pageurl": self.params["pageurl"],
"json": 1,
}
# Only include data-s when it exists
if "data-s" in self.params:
payload["data-s"] = self.params["data-s"]
return payload
# Usage
extractor = RecaptchaExtractor("https://www.google.com/sorry/index?continue=...")
payload = extractor.build_solver_payload("YOUR_API_KEY")
# payload includes data-s only when present on the page
Payload dibangun kondisional, jadi satu fungsi ini aman untuk target Google maupun situs pihak ketiga — menghindari bug paling umum: mengirim data-s di halaman yang tidak memakainya.
Kesalahan data-s yang paling sering terjadi
| Kesalahan | Gejala | Perbaikan |
|---|---|---|
| Melewatkan data-s padahal ada | Validasi token gagal diam-diam | Selalu cek atribut data-s sebelum mengirim |
| Menyertakan data-s padahal tidak ada | Error solve atau permintaan ditolak | Sertakan data-s hanya jika atributnya ada di widget |
| Memakai ulang data-s antar-pemuatan halaman | Token tidak valid | Ekstrak data-s baru untuk tiap pemuatan halaman |
| Salah URL-encode data-s | Parameter salah format | Kirim nilai base64 mentah tanpa encoding tambahan |
| Memakai data-s basi (halaman dimuat menit lalu) | Token tidak cocok | Ekstrak data-s tepat sebelum dikirim ke solver |
Pertanyaan yang sering diajukan
Apa bedanya data-s dan token g-recaptcha-response?
Keduanya berbeda dan tidak saling menggantikan. data-s adalah masukan: token sesi yang Anda baca dari HTML halaman lalu kirim ke solver. g-recaptcha-response adalah keluaran: token hasil solve yang Anda tempelkan ke form target.
Bagaimana cara tahu halaman target memakai data-s?
Cari atribut data-s pada elemen <div> widget reCAPTCHA. Kalau ada, sertakan; kalau tidak, jangan. Utilitas RecaptchaExtractor di atas melakukan pengecekan ini otomatis.
Apakah reCAPTCHA Enterprise juga memakai data-s?
Untuk sebagian besar integrasi reCAPTCHA Enterprise pihak ketiga, data-s tidak muncul — yang relevan sitekey dan action. data-s tetap paling erat dengan halaman verifikasi milik Google sendiri.
Apakah CaptchaAI mendukung reCAPTCHA v2 dan v3?
Ya. CaptchaAI menyelesaikan reCAPTCHA v2 (termasuk kasus data-s) dan v3 lewat metode userrecaptcha yang sama; Anda tinggal menyesuaikan parameter di in.php sesuai widget target.
Ringkasan
data-s adalah token pengikat sesi pada sebagian kecil implementasi reCAPTCHA, terutama properti Google seperti Google Search. Ekstrak dari HTML widget dan sertakan di permintaan API CaptchaAI. Aturannya: cek keberadaan data-s, sertakan bila ada, lewati bila tidak, dan ambil nilai baru tiap pemuatan halaman. Khusus Google Search, data-s selalu wajib.
Artikel Terkait
- Cara menyelesaikan callback reCAPTCHA v2 lewat API
- Menangani reCAPTCHA v2 dan Turnstile di satu situs
- Siklus hidup token reCAPTCHA