Playwright tek başına bir CAPTCHA çözmez — ve buna gerek de yok. Görev dağılımı nettir: Playwright, Chromium, Firefox ve WebKit üzerinde tarayıcıyı sürer; CaptchaAI ise doğrulamayı sunucu tarafında çözüp size geçerli bir token döndürür. Bu rehberde sitekey'i çıkarma, token'ı API ile alma ve sayfaya enjekte etme adımlarını Python ve Node.js için çalışan kodla göreceksiniz.
Tipik senaryo: Türkiye'deki bir e-ticaret ekibinin tr-TR yerel ayarıyla çalışan giriş akışını staging ortamında test etmesi. Sayfa bir reCAPTCHA veya Turnstile döndürdüğünde test otomasyonu durur; çözümü akışa eklediğinizde senaryo kesintisiz ilerler. CaptchaAI thread bazlı ve USD fiyatlandırıldığı için — BASIC ($15/ay, 5 thread) — aylık maliyet TL kurundan bağımsız kalır.
Çözüm akışı nasıl işler
Entegrasyonun tamamı dört adıma iner ve üç otomasyon aracı için de aynıdır:
- Tespit: Playwright, sayfadaki
.g-recaptchaveya.cf-turnstileöğesini bulur. - Çıkarım:
data-sitekeydeğeri okunur ve sayfa URL'siyle birlikte CaptchaAI'ye gönderilir. - Çözüm: CaptchaAI görevi sunucu tarafında çözer; siz
res.phpuç noktasını periyodik sorgulayarak token'ı beklersiniz. - Enjeksiyon: Dönen token ilgili alana yazılır ve form gönderilir.
Bu ayrım sayesinde tarayıcı tarafı hafif kalır: ağır iş CaptchaAI'nin thread havuzunda yürür, Playwright yalnızca DOM ile ilgilenir. Aşağıdaki bölümler bu dört adımı Python ve Node.js için çalışan kodla gösterir.
Başlamadan önce: gereksinimler
| Gereksinim | Ayrıntılar |
|---|---|
| Python | pip install playwright requests ardından playwright install |
| Node.js | npm install playwright axios |
| CaptchaAI API anahtarı | captchaai.com üzerinden alın |
Python ile Playwright + CaptchaAI entegrasyonu
Kurulum ve çözüm fonksiyonu
CaptchaAI'ye görevi gönderip sonucu sorgulayan yardımcı fonksiyonu tanımlayın. in.php görevi kuyruğa alır; token hazır olana kadar res.php 5 saniyede bir sorgulanır.
from playwright.sync_api import sync_playwright
import requests
import time
API_KEY = "YOUR_API_KEY"
def solve_recaptcha(site_key, page_url):
resp = requests.get("https://ocr.captchaai.com/in.php", params={
"key": API_KEY,
"method": "userrecaptcha",
"googlekey": site_key,
"pageurl": page_url
})
if not resp.text.startswith("OK|"):
raise Exception(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": API_KEY, "action": "get", "id": task_id
})
if result.text == "CAPCHA_NOT_READY": continue
if result.text.startswith("OK|"): return result.text.split("|")[1]
raise Exception(result.text)
raise TimeoutError()
Giriş formunda tam akış
Aşağıdaki fonksiyon formu doldurur, .g-recaptcha öğesini arar, sitekey'i çıkarır ve dönen token'ı g-recaptcha-response alanına yazar.
def login_with_captcha(url, username, password):
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
context = browser.new_context(
user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
)
page = context.new_page()
page.goto(url)
# Fill login form
page.fill("#username", username)
page.fill("#password", password)
# Check for reCAPTCHA
recaptcha = page.query_selector(".g-recaptcha")
if recaptcha:
site_key = recaptcha.get_attribute("data-sitekey")
print(f"Solving reCAPTCHA: {site_key}")
token = solve_recaptcha(site_key, page.url)
# Inject token
page.evaluate(f"""
document.getElementById('g-recaptcha-response').innerHTML = '{token}';
document.getElementById('g-recaptcha-response').style.display = '';
""")
# Submit
page.click('button[type="submit"]')
page.wait_for_load_state("networkidle")
print(f"Current URL: {page.url}")
content = page.content()
browser.close()
return content
result = login_with_captcha(
"https://staging.example.com/qa-login",
"user@example.com",
"password123"
)
Asenkron (async) sürüm
Çok sayıda sayfayı paralel işleyen iş akışları için async API ve aiohttp ile aynı mantığı bloklamadan çalıştırın.
from playwright.async_api import async_playwright
import aiohttp
import asyncio
async def solve_recaptcha_async(site_key, page_url):
async with aiohttp.ClientSession() as session:
params = {
"key": API_KEY, "method": "userrecaptcha",
"googlekey": site_key, "pageurl": page_url
}
async with session.get("https://ocr.captchaai.com/in.php", params=params) as resp:
text = await resp.text()
task_id = text.split("|")[1]
for _ in range(60):
await asyncio.sleep(5)
params = {"key": API_KEY, "action": "get", "id": task_id}
async with session.get("https://ocr.captchaai.com/res.php", params=params) as resp:
text = await resp.text()
if text == "CAPCHA_NOT_READY": continue
if text.startswith("OK|"): return text.split("|")[1]
raise Exception(text)
raise TimeoutError()
async def main():
async with async_playwright() as p:
browser = await p.chromium.launch(headless=True)
page = await browser.new_page()
await page.goto("https://example.com/form")
site_key = await page.get_attribute(".g-recaptcha", "data-sitekey")
token = await solve_recaptcha_async(site_key, page.url)
await page.evaluate(f"document.getElementById('g-recaptcha-response').innerHTML = '{token}'")
await page.click('button[type="submit"]')
await browser.close()
asyncio.run(main())
Node.js ile Playwright + CaptchaAI
Node.js karşılığı axios ile çözümü gönderir ve token'ı page.evaluate() içinde enjekte eder.
const { chromium } = require("playwright");
const axios = require("axios");
const API_KEY = "YOUR_API_KEY";
async function solveRecaptcha(siteKey, pageUrl) {
const submit = await axios.get("https://ocr.captchaai.com/in.php", {
params: {
key: API_KEY,
method: "userrecaptcha",
googlekey: siteKey,
pageurl: pageUrl,
},
});
const taskId = submit.data.split("|")[1];
while (true) {
await new Promise((r) => setTimeout(r, 5000));
const result = await axios.get("https://ocr.captchaai.com/res.php", {
params: { key: API_KEY, action: "get", id: taskId },
});
if (result.data === "CAPCHA_NOT_READY") continue;
if (result.data.startsWith("OK|")) return result.data.split("|")[1];
throw new Error(result.data);
}
}
(async () => {
const browser = await chromium.launch({ headless: true });
const page = await browser.newPage();
await page.goto("https://staging.example.com/qa-login");
// Fill form
await page.fill("#username", "user@example.com");
await page.fill("#password", "password123");
// Solve CAPTCHA
const siteKey = await page.getAttribute(".g-recaptcha", "data-sitekey");
if (siteKey) {
const token = await solveRecaptcha(siteKey, page.url());
await page.evaluate(
(t) => (document.getElementById("g-recaptcha-response").innerHTML = t),
token
);
}
// Submit
await page.click('button[type="submit"]');
await page.waitForLoadState("networkidle");
console.log("Logged in:", page.url());
await browser.close();
})();
Cloudflare Turnstile doğrulamasını çözme
Sayfa Cloudflare Turnstile döndürüyorsa mantık aynı kalır; yalnızca seçici .cf-turnstile, method değeri turnstile ve parametre sitekey olur. CaptchaAI Turnstile'ı GA olarak çözer.
# Detect Turnstile
turnstile = page.query_selector(".cf-turnstile")
if turnstile:
site_key = turnstile.get_attribute("data-sitekey")
resp = requests.get("https://ocr.captchaai.com/in.php", params={
"key": API_KEY, "method": "turnstile",
"sitekey": site_key, "pageurl": page.url
})
task_id = resp.text.split("|")[1]
# Poll and inject...
Dikkat edilecek tek fark parametre adıdır: reCAPTCHA'da googlekey gönderirken Turnstile'da sitekey gönderirsiniz. En sık yapılan hata, reCAPTCHA örneğinden kopyalarken method değerini turnstile yapıp parametre adını googlekey bırakmaktır. Token yine res.php üzerinden sorgulanır ve .cf-turnstile alanına enjekte edilir.
Playwright, Selenium ve Puppeteer karşılaştırması
Üç araç da CaptchaAI ile aynı şekilde entegre olur; fark otomasyon ergonomisindedir.
| Özellik | Playwright | Selenium | Puppeteer |
|---|---|---|---|
| Diller | Python, Node.js, C#, Java | Python, Java, C#, Ruby, JS | Node.js |
| Tarayıcılar | Chromium, Firefox, WebKit | Chrome, Firefox, Edge, Safari | Chromium |
| Otomatik bekleme | ✅ Yerleşik | ⏳ Manuel beklemeler | ⚠️ Kısmi |
| Ağ müdahalesi | ✅ | Sınırlı | ✅ |
| CaptchaAI entegrasyonu | ✅ Aynı API | ✅ Aynı API | ✅ Aynı API |
CaptchaAI üçünde de aynı adımlarla çalışır: sitekey'i çıkarın, API ile çözün, token'ı enjekte edin.
Üretimde ölçeklendirme ve thread yönetimi
Tekil bir test akışında tek thread yeterlidir; ancak CI/CD hattında onlarca senaryoyu paralel çalıştırdığınızda eşzamanlı çözüm sayısı planınızın thread limitine bağlıdır. BASIC ($15/ay, 5 thread) küçük bir QA süiti için başlangıç noktasıdır; paralel senaryo sayınız arttıkça daha yüksek thread sunan bir plana geçebilirsiniz.
Pratik öneriler:
- Async sürümü kullanarak
res.phpsorgulamalarını bloklamadan yürütün; böylece tek bir olay döngüsünde birden çok görevi beklersiniz. - Thread limitine takıldığınızda görevleri bir kuyruğa alın ve sorgulama aralığını 5 saniyenin altına indirmeyin — gereksiz istek yalnızca hız sınırına yaklaştırır.
- Fiyatlandırma USD ve aylık olduğu için maliyet tahmini TL kurundan değil, ihtiyaç duyduğunuz paralel thread sayısından çıkarılır.
Yetkili test kapsamı ve KVKK
Bu akışları yalnızca sahibi olduğunuz ya da test etme yetkiniz bulunan sistemlerde çalıştırın; örneklerdeki staging.example.com gibi kendi staging ortamınızı hedefleyin. Kişisel veri toplayan senaryolarda kazınan verilerin KVKK kapsamına girdiğini unutmayın ve CAPTCHA çözümünü yetkili QA ile veri toplama iş akışlarıyla sınırlayın.
Sorun giderme
| Sorun | Çözüm |
|---|---|
page.query_selector null döndürüyor |
CAPTCHA dinamik yükleniyor; page.wait_for_selector() kullanın |
| Token enjeksiyonu çalışmıyor | Yanıt textarea'sının farklı bir kimliği (ID) olabilir; kontrol edin |
| Playwright Docker'da çöküyor | Tarayıcı bağımlılıklarını kurun: playwright install-deps |
| Çözümden sonra CAPTCHA yeniden beliriyor | Site callback yürütülmesini bekliyor olabilir; page.evaluate() ile tetikleyin |
Sık sorulan sorular
CaptchaAI'yi Playwright'a bağlamak için ayrı bir SDK gerekir mi?
Hayır. Çözüm tamamen HTTP üzerinden yürür: requests, axios ya da herhangi bir HTTP istemcisiyle in.php ve res.php uç noktalarına istek atmanız yeterlidir. Playwright yalnızca sitekey'i çıkarır ve token'ı enjekte eder.
Çözümden sonra CAPTCHA neden yeniden beliriyor?
Genellikle sitenin bir callback fonksiyonunu beklemesinden kaynaklanır. Token'ı ilgili alana yazdıktan sonra, formu göndermeden önce callback'i page.evaluate() ile tetikleyin.
CaptchaAI hCaptcha'yı destekliyor mu?
Hayır. CaptchaAI reCAPTCHA v2/v3, Cloudflare Turnstile ve Challenge, GeeTest v3, görüntü/OCR ve grid türlerini çözer; hCaptcha ve FunCaptcha desteklenmez. CaptchaFox, Friendly Captcha ve Lemin ise beta aşamasındadır.
Headless modda çözüm oranı düşer mi?
Hayır. Çözüm işlemi CaptchaAI tarafında, tarayıcıdan bağımsız gerçekleşir; token üretimi açısından headless=True ile headless=False arasında fark yoktur.
Aynı anda kaç CAPTCHA çözebilirim?
Eşzamanlı çözüm sayısı planınızın thread limitine eşittir: BASIC ($15/ay, 5 thread) ile beş görevi paralel yürütebilirsiniz. Daha fazlası için async sürümü kullanın ve thread sayısı yüksek bir plan seçin.