Untuk menyelesaikan reCAPTCHA v2 di otomatisasi browser mobile, Anda tidak perlu perangkat fisik: emulasi mobile bawaan Playwright atau Selenium sudah cukup, dan token hasil solve dari CaptchaAI di-inject persis seperti di desktop. Yang berbeda bukan proses solve-nya, melainkan konteks di sekitarnya — User-Agent mobile, tata letak responsif, dan interaksi touch.
Tutorial ini menempuh dua jalur yang paling sering dipakai: Playwright dengan emulasi iPhone di desktop, dan Selenium dengan mobile emulation lewat Chrome DevTools Protocol — keduanya menghasilkan token reCAPTCHA valid tanpa handset nyata.
Apa yang membuat CAPTCHA mobile berbeda
Solve-nya identik dengan desktop; yang berubah hanya sinyal browser dan cara widget dirender.
| Faktor | Desktop | Mobile | Dampak pada CAPTCHA |
|---|---|---|---|
| User-Agent | Chrome/Firefox desktop | Safari/Chrome mobile | Sebagian situs menyajikan konfigurasi CAPTCHA berbeda per perangkat |
| Viewport | 1920×1080+ | 390×844 | Widget CAPTCHA bisa tampil dengan tata letak berbeda |
| Interaksi | Mouse event | Touch event | Beberapa CAPTCHA memvalidasi jenis interaksi |
| Jaringan | Broadband | 4G/5G | Batas waktu yang lebih longgar kadang diperlukan |
Dalam praktik, dua hal ini yang paling menentukan. Pertama, User-Agent yang Anda pakai saat solve harus sama persis dengan yang dipakai saat submit — server kerap menolak token bila keduanya berbeda. Kedua, di pasar yang mobile-first seperti Indonesia banyak pengujian berjalan di atas jaringan seluler, jadi bila situs lambat merender, longgarkan timeout dan interval polling agar solve tidak gugur sebelum halaman siap.
Skenario: form mobile dengan reCAPTCHA v2
Bayangkan proyek automasi pengisian form pada situs yang dioptimalkan untuk mobile — kasus lumrah bagi freelancer scraping dan tim price-monitoring. Situs mendeteksi User-Agent mobile lalu menampilkan tata letak reCAPTCHA v2 khusus mobile, dan Anda perlu solve lalu submit dari konteks itu. Batasi automasi pada situs milik sendiri atau staging (staging.example.com) dan proses hanya data yang berhak Anda olah — sejalan dengan UU Pelindungan Data Pribadi (UU 27/2022).
Pendekatan 1: emulasi mobile Playwright (Python)
Emulasi perangkat Playwright adalah cara paling ringkas menjalankan browser mobile berikut penyelesaian CAPTCHA. Skrip berikut meluncurkan konteks iPhone 13, mengambil sitekey, mengirim task ke CaptchaAI, lalu meng-inject token dan memicu callback:
import asyncio
import httpx
from playwright.async_api import async_playwright
API_KEY = "YOUR_API_KEY"
async def solve_recaptcha(sitekey: str, pageurl: str) -> str:
"""Submit reCAPTCHA v2 to CaptchaAI and poll for result."""
async with httpx.AsyncClient(timeout=180) as client:
# Submit task
resp = await client.get(
"https://ocr.captchaai.com/in.php",
params={
"key": API_KEY,
"method": "userrecaptcha",
"googlekey": sitekey,
"pageurl": pageurl,
"json": "1",
},
)
result = resp.json()
if result["status"] != 1:
raise Exception(f"Submit failed: {result['request']}")
task_id = result["request"]
# Poll for result
for _ in range(30):
await asyncio.sleep(5)
poll = await client.get(
"https://ocr.captchaai.com/res.php",
params={
"key": API_KEY,
"action": "get",
"id": task_id,
"json": "1",
},
)
poll_result = poll.json()
if poll_result["status"] == 1:
return poll_result["request"]
if poll_result["request"] != "CAPCHA_NOT_READY":
raise Exception(f"Solve failed: {poll_result['request']}")
raise Exception("Polling timeout")
async def main():
async with async_playwright() as p:
# Launch with iPhone 13 emulation
iphone = p.devices["iPhone 13"]
browser = await p.chromium.launch(headless=False)
context = await browser.new_context(**iphone)
page = await context.new_page()
await page.goto("https://example.com/mobile-form")
await page.wait_for_selector(".g-recaptcha", timeout=10000)
# Extract sitekey
sitekey = await page.get_attribute(".g-recaptcha", "data-sitekey")
pageurl = page.url
print(f"Found sitekey: {sitekey}")
# Solve via CaptchaAI
token = await solve_recaptcha(sitekey, pageurl)
print(f"Token received: {token[:50]}...")
# Inject token
await page.evaluate(f"""
document.getElementById('g-recaptcha-response').value = '{token}';
document.getElementById('g-recaptcha-response').style.display = '';
""")
# Trigger callback if it exists
await page.evaluate(f"""
try {{
const clients = ___grecaptcha_cfg.clients;
Object.keys(clients).forEach(k => {{
Object.keys(clients[k]).forEach(j => {{
if (clients[k][j] && clients[k][j].callback) {{
clients[k][j].callback('{token}');
}}
}});
}});
}} catch(e) {{}}
""")
# Submit form
await page.click('button[type="submit"]')
await page.wait_for_load_state("networkidle")
print("Form submitted successfully")
await browser.close()
asyncio.run(main())
Pola empat langkahnya konsisten di semua bahasa: kirim task ke in.php, simpan task ID, polling res.php sampai token siap, lalu inject token ke textarea g-recaptcha-response dan picu callback. Karena emulasi berjalan di desktop, tidak ada perangkat fisik yang perlu di-maintain, sehingga pola ini cocok untuk pipeline CI/CD.
Pendekatan 2: Selenium dengan mobile emulation (Node.js)
Untuk alur kerja Node.js, gunakan Selenium dengan mobile emulation Chrome DevTools Protocol. deviceMetrics dan userAgent diset eksplisit agar sinyal browser konsisten hingga submit:
// selenium_mobile_captcha.js
const { Builder, By, until } = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const axios = require('axios');
const API_KEY = 'YOUR_API_KEY';
async function solveCaptcha(sitekey, pageurl) {
// Submit task
const submitResp = await axios.get('https://ocr.captchaai.com/in.php', {
params: {
key: API_KEY,
method: 'userrecaptcha',
googlekey: sitekey,
pageurl: pageurl,
json: '1',
},
});
if (submitResp.data.status !== 1) {
throw new Error(`Submit failed: ${submitResp.data.request}`);
}
const taskId = submitResp.data.request;
// Poll for result
for (let i = 0; i < 30; i++) {
await new Promise((r) => setTimeout(r, 5000));
const pollResp = await axios.get('https://ocr.captchaai.com/res.php', {
params: { key: API_KEY, action: 'get', id: taskId, json: '1' },
});
if (pollResp.data.status === 1) return pollResp.data.request;
if (pollResp.data.request !== 'CAPCHA_NOT_READY') {
throw new Error(`Solve failed: ${pollResp.data.request}`);
}
}
throw new Error('Polling timeout');
}
async function main() {
// Configure mobile emulation
const mobileEmulation = {
deviceMetrics: { width: 390, height: 844, pixelRatio: 3.0 },
userAgent:
'Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) ' +
'AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Mobile/15E148 Safari/604.1',
};
const options = new chrome.Options();
options.setMobileEmulation(mobileEmulation);
const driver = await new Builder()
.forBrowser('chrome')
.setChromeOptions(options)
.build();
try {
await driver.get('https://example.com/mobile-form');
await driver.wait(until.elementLocated(By.css('.g-recaptcha')), 10000);
// Extract sitekey
const captchaEl = await driver.findElement(By.css('.g-recaptcha'));
const sitekey = await captchaEl.getAttribute('data-sitekey');
const pageurl = await driver.getCurrentUrl();
console.log(`Sitekey: ${sitekey}`);
// Solve CAPTCHA
const token = await solveCaptcha(sitekey, pageurl);
console.log(`Token: ${token.substring(0, 50)}...`);
// Inject token
await driver.executeScript(`
document.getElementById('g-recaptcha-response').value = arguments[0];
`, token);
// Submit form
await driver.findElement(By.css('button[type="submit"]')).click();
console.log('Form submitted');
} finally {
await driver.quit();
}
}
main().catch(console.error);
Perbedaan utama dari Playwright ada pada cara emulasi disusun: di sini Anda menyetel deviceMetrics dan userAgent secara manual, bukan memakai profil perangkat siap pakai. Fungsi solveCaptcha sendiri identik secara alur dengan versi Python — kirim, polling, kembalikan token.
Playwright atau Selenium: mana yang dipilih
Keduanya sama-sama valid; pilih berdasarkan stack Anda. Playwright unggul untuk proyek Python baru karena profil perangkat bawaan (p.devices["iPhone 13"]) langsung menyetel viewport, User-Agent, dan device scale factor sekaligus, sehingga sinyal mobile-nya konsisten tanpa konfigurasi tambahan. Selenium lebih masuk akal bila Anda sudah punya infrastruktur Selenium Grid atau tim yang terbiasa dengannya. Untuk kebutuhan sinyal perangkat yang lebih ketat, perangkat nyata via Appium adalah opsi berikutnya — tetapi untuk mayoritas alur pengisian form, emulasi sudah memadai dan jauh lebih murah dijalankan.
Menjaga konsistensi User-Agent
Penyebab kegagalan paling umum bukan solve yang keliru, melainkan mismatch User-Agent. CaptchaAI mengembalikan token hanya dari sitekey dan page URL, jadi token selalu valid — tetapi server target bisa menolak submit bila User-Agent saat solve berbeda dari saat form dikirim. Pakai satu User-Agent mobile yang sama di seluruh sesi, dan bila Anda meneruskan proxy ke CaptchaAI, gunakan egress jaringan yang sama agar keseluruhan konteks tetap koheren.
Mengatasi masalah yang sering muncul
Kegagalan pada emulasi mobile hampir selalu soal sinyal browser atau rendering widget, bukan solve-nya.
| Masalah | Penyebab | Penanganan |
|---|---|---|
| CAPTCHA tidak muncul dalam emulasi mobile | Situs mendeteksi emulasi lewat navigator.platform |
Set platform override di DevTools Protocol |
Textarea g-recaptcha-response tidak ditemukan |
Tata letak mobile memakai rendering CAPTCHA yang berbeda | Cari textarea berdasarkan atribut name, bukan ID |
| Token sudah di-set tapi form tetap gagal | Server memvalidasi konsistensi User-Agent | Pakai User-Agent yang sama untuk solve dan submit form |
| Pemuatan halaman lambat di emulasi | Halaman berat oleh banyak resource | Aktifkan flag Chrome --disable-images untuk mempercepat loading |
Pertanyaan umum
Berapa lama waktu penyelesaian reCAPTCHA v2 pada browser mobile?
Sama dengan desktop — konteks mobile tidak mengubah durasi solve, karena CaptchaAI hanya memproses sitekey dan page URL. Yang menambah waktu justru jaringan seluler.
Apakah emulasi mobile menurunkan tingkat keberhasilan solve?
Tidak. Token yang dikembalikan valid terlepas dari perangkat. Kegagalan yang tampak "karena mobile" biasanya karena User-Agent tidak konsisten antara solve dan submit — masalah integrasi, bukan solve.
Bagaimana dengan hCaptcha di situs mobile?
hCaptcha tidak didukung, baik di desktop maupun mobile. CaptchaAI menyelesaikan reCAPTCHA v2/v3, Cloudflare Turnstile dan Challenge, GeeTest v3, serta CAPTCHA image/grid. Untuk hCaptcha Anda memerlukan layanan lain.
Bisakah emulasi mobile dipadukan dengan proxy?
Bisa. Playwright maupun Selenium mendukung konfigurasi proxy bersama emulasi mobile. Teruskan egress jaringan yang sama ke CaptchaAI agar konteks solve dan submit konsisten.
Bisakah token reCAPTCHA dipakai ulang antar-request?
Tidak. Token reCAPTCHA bersifat sekali pakai dan kedaluwarsa dalam waktu singkat, jadi selesaikan CAPTCHA baru untuk setiap submit form.
Artikel Terkait
- Menyelesaikan callback reCAPTCHA v2 via API
- Menangani reCAPTCHA v2 dan Turnstile di satu situs
- Mengekstrak parameter reCAPTCHA dari sumber halaman