Mobil tarayıcı otomasyonunda reCAPTCHA v2 çözmenin en pratik yolu, doğrulamayı CaptchaAI API'sine göndermek ve dönen token'ı sayfaya enjekte etmektir. CAPTCHA'nın mobil düzende mi yoksa masaüstü düzende mi oluşturulduğu çözüm sürecini değiştirmez: gönderdiğiniz sitekey ve pageurl her iki bağlamda da aynıdır. Değişen tek şey CAPTCHA'yı çevreleyen tarayıcıdır.
Bu rehberde fiziksel cihaz gerektirmeyen iki yöntemi ele alıyoruz: masaüstünde Playwright'ın cihaz emülasyonu ve Selenium'un Chrome DevTools Protocol (CDP) mobil emülasyonu. Her iki yöntemde de çözüm akışı aynı dört adımdan oluşur:
- Sayfadaki
.g-recaptchaöğesindensitekeydeğerini çıkarın. sitekeyvepageurl'i CaptchaAI'ninin.phpuç noktasına gönderin.res.phpuç noktasını sorgulayarak çözülmüş token'ı alın.- Token'ı
g-recaptcha-responsealanına enjekte edip varsa callback'i tetikleyin.
Cihaz emülasyonu yalnızca bu akışı çevreleyen tarayıcı bağlamını değiştirir; API'ye giden istek her iki bağlamda da birebir aynıdır.
Mobil ve masaüstü CAPTCHA çözümü arasındaki farklar
Mobil otomasyon, masaüstüyle aynı CAPTCHA ailelerini görür: reCAPTCHA onay kutuları, Cloudflare doğrulama akışları ve görüntü ızgaraları. Fark, CAPTCHA'nın kendisinde değil onu çevreleyen bağlamdadır: mobil User-Agent gören site farklı bir düzen sunabilir, dokunma etkileşimleri bekleyebilir, görünüm alanı daralır. Aşağıdaki tablo dikkat edilecek noktaları özetler.
| Faktör | Masaüstü | Mobil | CAPTCHA'ya etkisi |
|---|---|---|---|
| User-Agent | Masaüstü Chrome/Firefox | Mobil Safari/Chrome | Bazı siteler cihaza göre farklı CAPTCHA yapılandırması sunar |
| Görünüm alanı (viewport) | 1920×1080+ | 390×844 | CAPTCHA widget'ı farklı oluşturulabilir |
| Etkileşim | Fare olayları | Dokunma (touch) olayları | Bazı CAPTCHA'lar etkileşim türünü doğrular |
| Ağ | Geniş bant | 4G/5G | Daha uzun zaman aşımı gerekebilir |
Örnek senaryo: mobile özel reCAPTCHA v2 formu
Türkiye'deki bir ekipte, mobil öncelikli bir e-ticaret sitesinin form gönderimini QA testinden geçiriyorsunuz. Site, mobil User-Agent'ları algılıyor ve mobile özel bir CAPTCHA düzeni oluşturuyor. Göreviniz net: reCAPTCHA v2'yi çözmek ve formu mobil tarayıcı bağlamından göndermek. Kişisel veri toplayan akışlarda KVKK kapsamında yalnızca yetkili olduğunuz veriler üzerinde çalışın.
Yöntem 1: Playwright mobil emülasyonu ile CAPTCHA çözme (Python)
Playwright'ın cihaz emülasyonu, mobil tarayıcıları CAPTCHA çözümüyle otomatikleştirmenin en basit yoludur ve fiziksel bir cihaz gerektirmez. Aşağıdaki betik, iPhone 13 profiliyle bir bağlam açar, sitekey'i çıkarır, CaptchaAI'ye gönderir ve dönen token'ı sayfaya enjekte eder.
# playwright_mobile_captcha.py
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())
Token'ı g-recaptcha-response alanına yazdıktan sonra, varsa callback'i ___grecaptcha_cfg üzerinden tetikleyin; çoğu formda gönderimin başarılı olması buna bağlıdır.
Yöntem 2: Selenium mobil emülasyonu ile CAPTCHA çözme (JavaScript)
Node.js iş akışları için aynı mantığı Selenium ve Chrome DevTools Protocol mobil emülasyonuyla kurabilirsiniz. Cihaz metriklerini ve User-Agent'ı elle tanımlar, çözüm akışını Python örneğindeki adım sırasıyla yürütürsünüz.
// 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);
Selenium örneğinde token'ı arguments[0] üzerinden enjekte etmek, token'ı doğrudan betiğe gömmeye kıyasla dize kaçış sorunlarını ortadan kaldırır; uzun token değerlerinde bu küçük fark gönderimi bozan tırnak hatalarını önler.
User-Agent tutarlılığını koruyun
Mobil emülasyonda en sık gözden kaçan nokta, çözüm ile form gönderimi arasında User-Agent'ın değişmesidir. CaptchaAI'ye görevi gönderirken tarayıcı bir mobil User-Agent kullanıyor, ancak token'ı enjekte ettikten sonraki istek masaüstü bir başlıkla gidiyorsa, sunucu bu tutarsızlığı fark edip geçerli bir token'a rağmen formu reddedebilir. Şu üç değeri baştan sona eşleştirin:
- Emülasyon profilinin User-Agent değeri
- Görünüm alanı (viewport) boyutları ve
pixelRatio - Sonraki HTTP isteklerinde gönderilen
User-Agentbaşlığı
Emülasyon profilinde tanımladığınız User-Agent'ı tüm istek zinciri boyunca sabit tutun.
Playwright'ta iPhone 13 profili User-Agent'ı, görünüm alanını ve dokunma desteğini birlikte ayarlar; ek istekleri aynı context üzerinden yaparsanız başlık kendiliğinden korunur. Selenium tarafında ise deviceMetrics ile userAgent'ı elle eşleştirmeniz gerekir — biri iPhone, diğeri Android metriği taşırsa görünüm alanı ile User-Agent çelişir ve bazı siteler bu çelişkiyi bot sinyali olarak yorumlar. Cihaz profilini bir yerde sabitleyip hem tarayıcıya hem de sonraki HTTP isteklerine aynı değerleri vermek en güvenli yaklaşımdır.
Mobil emülasyonda sık karşılaşılan sorunlar
Mobil emülasyonda çoğu hata, CAPTCHA çözümünden değil tarayıcı ile sunucu arasındaki tutarsızlıktan kaynaklanır. En sık görülenler ve çözümleri:
| Sorun | Neden | Çözüm |
|---|---|---|
| CAPTCHA emülasyonda oluşmuyor | Site, emülasyonu navigator.platform üzerinden algılıyor |
DevTools Protocol'de platform geçersiz kılmayı ayarlayın |
g-recaptcha-response textarea bulunamıyor |
Mobil düzen farklı bir CAPTCHA oluşturma kullanıyor | textarea'yı ID yerine name özniteliğine göre arayın |
| Token enjekte ediliyor ama form yine başarısız oluyor | Sunucu, User-Agent tutarlılığını doğruluyor | Çözüm ve form gönderiminde aynı User-Agent'ı kullanın |
| Emülasyonda sayfa yavaş yükleniyor | Kaynak ağırlıklı sayfalar | Yüklemeyi hızlandırmak için --disable-images Chrome bayrağını kullanın |
Sık sorulan sorular
Playwright mı yoksa Selenium mı kullanmalıyım?
Sıfırdan bir mobil emülasyon kuruyorsanız Playwright daha az kodla başlar: cihaz profilleri (iPhone 13 gibi) hazır gelir. Ekibiniz zaten Selenium tabanlı bir test altyapısı kullanıyorsa, CDP mobil emülasyonuyla aynı çözüm akışını mevcut yığınınıza taşımak daha mantıklıdır. İkisi de aynı CaptchaAI uç noktalarını kullanır.
Mobil CAPTCHA çözümünün maliyeti nedir?
CaptchaAI thread bazlı fiyatlandırır; çözüm başına ücret yoktur. BASIC plan ($15/ay, 5 thread) ile başlayabilir, mobil ve masaüstü çözümlerinizi aynı bakiyeden yürütebilirsiniz. Aylık USD fiyatlar TL'deki oynaklıktan bağımsız olarak öngörülebilir kalır.
CaptchaAI CAPTCHA'nın mobil olduğunu bilmeli mi?
Hayır. CaptchaAI yalnızca sitekey ve pageurl üzerinden çözer; mobil ya da masaüstü ayrımı çözüm sürecini etkilemez. Aynı sitekey her iki bağlamda da geçerli bir token döndürür.
CaptchaAI hangi CAPTCHA türlerini çözer, mobil hCaptcha dahil mi?
CaptchaAI reCAPTCHA v2 ve v3, Cloudflare Turnstile ve Challenge, GeeTest v3, görüntü/OCR, grid ve BLS CAPTCHA'larını çözer; CaptchaFox (beta), Friendly Captcha (beta) ve Lemin (beta) ise beta aşamasındadır. hCaptcha ve FunCaptcha şu anda desteklenmez. Bu rehberdeki mobil akış reCAPTCHA v2 içindir.
Token'ı enjekte ettim ama form yine gönderilmiyor, ne yapmalıyım?
Önce g-recaptcha-response alanının gerçekten dolduğunu tarayıcı konsolundan doğrulayın. Alan doluysa sorun genellikle callback'in tetiklenmemesidir: token'ı yazdıktan sonra ___grecaptcha_cfg üzerinden ilgili callback'i çağırın. Bu da işe yaramıyorsa, çözüm ve gönderim isteklerinde aynı User-Agent'ı kullandığınızdan emin olun — sunucu tarafı tutarsızlık, geçerli bir token'ı bile reddettirebilir.
İlgili Makaleler
- reCAPTCHA v2 callback CAPTCHA'sını API ile çözme
- Zapier ile kodsuz CaptchaAI otomasyonu
- Aynı sayfada reCAPTCHA v2 ve Turnstile'ı yönetme
Sonraki Adımlar
Mobil CAPTCHA akışlarını otomatikleştirmeye bugün başlayın: CaptchaAI API anahtarınızı alın ve mobil otomasyon yığınınıza entegre edin.
İlgili kılavuzlar: