Selenium ile bir formu otomatikleştirirken reCAPTCHA veya Turnstile karşınıza çıktığında yapmanız gereken tek şey var: doğrulamayı tarayıcıda tıklamaya çalışmak yerine CaptchaAI API'sine devredin. Selenium sayfayı yönetmeye devam eder; CaptchaAI CAPTCHA'yı sunucu tarafında çözer, siz de dönen token'ı sayfadaki yanıt alanına enjekte edip formu gönderirsiniz. Bu rehber tüm akışı dört adımda ve çalışan Python örnekleriyle gösterir.
Kısa yol: Selenium sitekey'i okur, CaptchaAI token'ı döndürür, siz token'ı forma yazıp gönderirsiniz. Tarayıcının CAPTCHA widget'ını tıklaması gerekmez.
Gereksinimler
| Gereksinim | Ayrıntılar |
|---|---|
| Python 3.7+ | pip kurulu olmalı |
| Selenium | pip install selenium |
| Chrome + ChromeDriver | Eşleşen sürümler |
| requests | pip install requests |
| CaptchaAI API anahtarı | captchaai.com üzerinden |
Akış nasıl işliyor?
- Selenium hedef sayfayı yükler.
- Komut dosyanız CAPTCHA sitekey'ini sayfanın DOM'undan çıkarır.
- CaptchaAI, sitekey ve sayfa URL'siyle CAPTCHA'yı çözer.
- Komut dosyanız dönen token'ı sayfaya enjekte eder ve formu gönderir.
CAPTCHA sunucu tarafında CaptchaAI tarafından çözülür; Selenium hiçbir zaman CAPTCHA widget'ıyla doğrudan etkileşime girmez. Bu ayrım, headless çalışmayı kolaylaştırır.
Örnek bir senaryo: bir e-ticaret ekibinde staging.example.com/qa-login giriş akışını her gece regresyon testinden geçiriyorsunuz ve formdaki reCAPTCHA testleri durduruyor. Doğrulamayı CaptchaAI'ye devrederek testleri kesintisiz çalıştırır, KVKK kapsamındaki gerçek kullanıcı verilerine dokunmadan yalnızca kendi staging ortamınızı doğrularsınız. Aynı yaklaşım, müşteri projelerini teslim tarihine yetiştiren freelance otomasyon geliştiricileri için de geçerlidir: tek bir entegrasyonla birden çok müşterinin QA akışında CAPTCHA sorununu kapatırsınız.
Neden sunucu tarafında çözmek?
CAPTCHA widget'ını tarayıcıda tıklamaya çalışmak kırılgan bir yaklaşımdır: reCAPTCHA'nın iframe yapısı sık değişir, görsel doğrulamalar Selenium'un otomatik tıklamalarını fark eder ve her sürüm güncellemesi betiğinizi bozabilir. Sitekey'i çıkarıp çözümü CaptchaAI'ye devretmek bu kırılganlığı azaltır — betiğiniz yalnızca iki sabit adımla ilgilenir: sitekey'i okumak ve dönen token'ı forma yazmak. Widget'ın iç yapısı değişse bile bu iki adım aynı kalır, dolayısıyla iş akışınızın bakımı kolaylaşır ve gece çalışan testler daha az kırılır.
Bu yaklaşımın somut kazanımları:
- Selenium betiği CAPTCHA sürümü güncellendiğinde yeniden yazılmaz.
- Headless çalışma sorunsuzlaşır, çünkü görsel etkileşime gerek kalmaz.
- Aynı çözücü fonksiyonu reCAPTCHA v2/v3 ve Turnstile arasında paylaşılır.
Adım 1: Selenium'u kurun
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
options = Options()
options.add_argument("--no-sandbox")
options.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36")
driver = webdriver.Chrome(options=options)
--no-sandbox bayrağı, özellikle Docker veya CI ortamlarında Chrome'un sorunsuz başlamasına yardımcı olur. Otomasyon bandını sadeleştirmek için standart yapılandırmaya şunu ekleyebilirsiniz:
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option("useAutomationExtension", False)
Adım 2: CAPTCHA çözücüyü oluşturun
import requests
import time
API_KEY = "YOUR_API_KEY"
def solve_recaptcha_v2(site_key, page_url):
"""Solve reCAPTCHA v2 using CaptchaAI API."""
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(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": 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(f"Solve failed: {result.text}")
raise TimeoutError("CAPTCHA solve timed out")
Bu fonksiyon görevi in.php'ye gönderir, ardından res.php'yi beş saniyede bir sorgulayarak token hazır olana kadar bekler.
Adım 3: sitekey'i çıkarın ve çözün
# Navigate to the target page
driver.get("https://staging.example.com/qa-login")
# Wait for the reCAPTCHA to load
wait = WebDriverWait(driver, 10)
recaptcha = wait.until(
EC.presence_of_element_located((By.CLASS_NAME, "g-recaptcha"))
)
# Extract the site key
site_key = recaptcha.get_attribute("data-sitekey")
page_url = driver.current_url
print(f"Site key: {site_key}")
print(f"Page URL: {page_url}")
# Solve the CAPTCHA
token = solve_recaptcha_v2(site_key, page_url)
print(f"Token received: {token[:50]}...")
Selenium sayfayı yükledikten sonra g-recaptcha öğesini bekler, data-sitekey özniteliğini okur ve değeri çözücüye geçirir.
Adım 4: token'ı enjekte edin ve gönderin
# Inject the token into the reCAPTCHA response field
driver.execute_script(f"""
document.getElementById('g-recaptcha-response').innerHTML = '{token}';
document.getElementById('g-recaptcha-response').style.display = '';
""")
# If the form uses a callback function, trigger it
driver.execute_script(f"""
if (typeof ___grecaptcha_cfg !== 'undefined') {{
Object.keys(___grecaptcha_cfg.clients).forEach(function(key) {{
var client = ___grecaptcha_cfg.clients[key];
if (client.callback) client.callback('{token}');
}});
}}
""")
# Submit the form
driver.find_element(By.CSS_SELECTOR, "form").submit()
# Wait for navigation
wait.until(EC.url_changes(page_url))
print(f"Success! Now on: {driver.current_url}")
Dönen token'ı g-recaptcha-response yanıt alanına yazın; site bir callback kullanıyorsa driver.execute_script() ile onu tetikleyin ve formu gönderin. Callback tabanlı reCAPTCHA'nın ayrıntıları için reCAPTCHA v2 callback çözme rehberine bakın.
Tam çalışan örnek
Yukarıdaki parçaları tek bir çalıştırılabilir betikte birleştiren tam sürüm:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import requests
import time
API_KEY = "YOUR_API_KEY"
def solve_recaptcha_v2(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(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": 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(f"Solve failed: {result.text}")
raise TimeoutError("Timed out")
def main():
options = Options()
options.add_argument("--no-sandbox")
driver = webdriver.Chrome(options=options)
try:
driver.get("https://staging.example.com/qa-login")
wait = WebDriverWait(driver, 10)
# Extract site key
recaptcha = wait.until(
EC.presence_of_element_located((By.CLASS_NAME, "g-recaptcha"))
)
site_key = recaptcha.get_attribute("data-sitekey")
# Solve
token = solve_recaptcha_v2(site_key, driver.current_url)
# Inject and submit
driver.execute_script(
f"document.getElementById('g-recaptcha-response').innerHTML = '{token}';"
)
driver.find_element(By.CSS_SELECTOR, "form").submit()
wait.until(EC.url_changes(driver.current_url))
print("Login successful!")
finally:
driver.quit()
if __name__ == "__main__":
main()
Diğer CAPTCHA türleri
Aynı sorgulama mantığı diğer türlerde de çalışır; yalnızca method ve parametreler değişir. reCAPTCHA v3 için version ve action, Turnstile için sitekey gönderin.
method ve parametre eşlemesi
| CAPTCHA türü | method |
Ek parametreler |
|---|---|---|
| reCAPTCHA v2 | userrecaptcha |
googlekey, pageurl |
| reCAPTCHA v3 | userrecaptcha |
googlekey, pageurl, version=v3, action |
| Cloudflare Turnstile | turnstile |
sitekey, pageurl |
reCAPTCHA v3
def solve_recaptcha_v3(site_key, page_url, action="verify"):
resp = requests.get("https://ocr.captchaai.com/in.php", params={
"key": API_KEY,
"method": "userrecaptcha",
"googlekey": site_key,
"pageurl": page_url,
"version": "v3",
"action": action
})
task_id = resp.text.split("|")[1]
# ... same polling logic
Cloudflare Turnstile
def solve_turnstile(site_key, page_url):
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]
# ... same polling logic
Üretimde dikkat edilmesi gerekenler
Tek seferlik bir betikten düzenli çalışan bir iş akışına geçerken birkaç nokta fark yaratır:
- Zaman aşımı ve yeniden deneme. Çözüm süresi ortama ve CAPTCHA türüne göre değişir;
res.phpsorgulamasını sabit bir üst sınıra bağlayın ve başarısız görevlerde üstel geri çekilme (exponential backoff) ile yeniden deneyin. Enjeksiyon ile form gönderimi arasını 120 saniyenin altında tutun, aksi halde token'ın süresi dolar. - Thread ölçekleme. Aynı anda kaç sayfayı test ettiğinize göre eşzamanlı çözüm sayısı artar. Plan thread sayısı bu eşzamanlılığın tavanıdır: gece çalışan tek bir regresyon paketi için BASIC ($15/ay, 5 thread) yeterliyken, paralel çalışan onlarca senaryoda daha yüksek thread'li bir tarifeye geçmeniz gerekir.
- Kapsam ve KVKK. Selenium akışınızı yalnızca sahibi olduğunuz staging ortamlarına ve yetkili test hesaplarına yöneltin. Gerçek kullanıcı verisi işleyen sayfalarda KVKK yükümlülükleri devreye girer; CAPTCHA çözümünü kendi QA verinizle sınırlı tutmak hem uyum hem de tekrarlanabilirlik açısından güvenli tarafta kalmanızı sağlar.
- Seçici bağımlılığı.
g-recaptchasınıfı yerine sayfanın gerçekten kullandığı seçiciyi doğrulayın; tek sayfa uygulamalarında (SPA) widget geç yüklenebilir, bu yüzdenWebDriverWaitsüresini cömert tutun.
Not: CaptchaAI hCaptcha ve FunCaptcha'yı desteklemez. Bu türlerle karşılaşırsanız akışı reCAPTCHA veya Turnstile varyantına göre uyarlayın; desteklenen türlerin tam listesi için ürün dokümanlarına bakın.
Sorun giderme
| Sorun | Neden | Çözüm |
|---|---|---|
| Token reddedildi | Token gönderilmeden önce süresi doldu | 120 saniye içinde enjekte edip gönderin |
| sitekey bulunamadı | CAPTCHA dinamik olarak yükleniyor | WebDriverWait süresini uzatın |
NoSuchElementException |
Yanlış seçici | Doğru öğeyi bulmak için sayfayı inceleyin |
| ChromeDriver sürüm uyuşmazlığı | Chrome güncellendi | Eşleşen ChromeDriver sürümünü indirin |
| Token doğru ama bot tespit ediliyor | CAPTCHA'nın ötesinde bir anti-bot katmanı var | İsteklerinize gerçekçi HTTP başlıkları ekleyin ve testleri standart bir tarayıcı profiliyle çalıştırın |
İpucu: Aynı hatayı tekrar tekrar alıyorsanız önce
in.phpyanıtını loglayın; sorun çoğu zaman eksikpageurlveya yanlışmethoddeğerinden kaynaklanır.
Sık sorulan sorular
CaptchaAI Selenium için hangi fiyattan başlıyor?
Planlar thread bazlıdır ve her thread için sınırsız çözüm içerir. En düşük tarife BASIC ($15/ay, 5 thread); aynı anda kaç CAPTCHA çözeceğinize göre thread sayısını yükseltirsiniz.
reCAPTCHA v3 ve Cloudflare Turnstile'ı da çözüyor mu?
Evet. Aynı Selenium akışında yalnızca method ve parametreleri değiştirerek reCAPTCHA v2/v3, Cloudflare Turnstile ve Challenge, GeeTest v3 ile görüntü/OCR CAPTCHA'larını çözebilirsiniz. hCaptcha ve FunCaptcha desteklenmez.
Token geçerli ama form neden reddediyor?
Çoğu zaman token gönderilmeden önce süresi dolmuştur; enjeksiyon ile gönderim arasını 120 saniyenin altında tutun. Sorun sürerse site, CAPTCHA dışında bir anti-bot katmanı çalıştırıyor olabilir.
Selenium'u headless modda kullanabilir miyim?
Evet. CaptchaAI CAPTCHA'yı sunucu tarafında çözdüğü için tarayıcının yalnızca sayfayı yükleyip sitekey'i çıkarması yeterlidir; headless mod sorunsuz çalışır.
Selenium yerine yalnızca requests ile çözebilir miyim?
Sitekey ve pageurl değerlerini elde edebiliyorsanız evet — token'ı almak için tarayıcı şart değildir. Ancak sitekey JavaScript ile dinamik oluşturuluyorsa, sayfayı çalıştırıp değeri okumanın en pratik yolu Selenium'dur; token'ı aldıktan sonra formu yine aynı oturumda gönderebilirsiniz.
Yayına almadan önce hızlı kontrol listesi
- API anahtarınızı
YOUR_API_KEYyerine ortam değişkeninden okuyun. - Enjeksiyon ile form gönderimi arasını 120 saniyenin altında tutun.
WebDriverWaitsüresini hedef sayfanın yüklenme davranışına göre ayarlayın.- Akışı yalnızca sahibi olduğunuz staging ortamlarında çalıştırın.