JavaScript ile render edilen bir sayfayı otomatikleştirirken CAPTCHA'ya takıldıysanız çözüm dört adımdan ibarettir: sayfadaki CAPTCHA türünü tespit edin, CaptchaAI API'sine gönderip token'ı alın, token'ı JavaScript ile sayfaya enjekte edin ve formu gönderin. Selenium tarayıcıyı sürerken CaptchaAI çözümü kendi tarafında hallettiği için ikisini birleştirmek reCAPTCHA v2/v3, Cloudflare Turnstile ve klasik resim CAPTCHA'larını tek bir iş akışında toplar.
Senaryo çoğu geliştiriciye tanıdık gelir: bir e-ticaret ödeme adımını ya da üyelik formunu QA amacıyla otomatikleştiriyorsunuz, ama giriş sayfası hem JavaScript render'ı hem de bir CAPTCHA istiyor. Bionluk veya Upwork üzerinden teslim tarihli otomasyon işi yürütenler için en çok zaman kaybettiren nokta tam da burasıdır. CaptchaAI thread tabanlı ve USD üzerinden faturalandığından — örneğin BASIC ($15/ay, 5 thread) — TL kurundaki oynaklıktan bağımsız, öngörülebilir bir maliyetle çalışırsınız.
Akışı, türden bağımsız olarak dört adıma indirgeyebilirsiniz:
- Tespit — sayfa kaynağından CAPTCHA türünü ve
sitekeydeğerini okuyun. - Çözüm — görevi CaptchaAI API'sine gönderip token'ı alın.
- Enjeksiyon — token'ı JavaScript ile gizli alana yazın.
- Gönderim — formu gönderin ve yönlendirmeyi doğrulayın.
Gerekli paketler
pip install selenium requests webdriver-manager
Üç paket üç ayrı işi üstlenir:
selenium— tarayıcıyı programatik olarak sürer.requests— CaptchaAI API'sine HTTP çağrısı yapar.webdriver-manager— doğru sürücü ikilisini sizin yerinize indirir.
Selenium sürücüsünü hazırlama
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
def create_driver():
"""Create a Selenium driver with QA testi-configuredion settings."""
options = webdriver.ChromeOptions()
options.add_argument("--no-sandbox")
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option("useAutomationExtension", False)
driver = webdriver.Chrome(
service=Service(ChromeDriverManager().install()),
options=options,
)
# Remove webdriver flag
driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
"source": "Object.defineProperty(navigator, 'webdriver', {get: () => undefined})"
})
return driver
ChromeDriverManager doğru sürücü ikilisini otomatik indirir, böylece sürüm uyumsuzluğuyla uğraşmazsınız. --no-sandbox bayrağı CI konteynerlerinde tarayıcıyı sorunsuz başlatmak için gereklidir; bu standart yapılandırma, QA test akışınızın kararlı çalışmasını sağlar.
Tekrar kullanılabilir CaptchaAI çözüm fonksiyonu
Tek bir yardımcı fonksiyon her CAPTCHA türü için kullanılabilir: görevi in.php uç noktasına gönderir, sonucu res.php üzerinden periyodik olarak sorgular ve token'ı döndürür.
import time
import requests
API_KEY = "YOUR_API_KEY"
def solve_captcha(method, **params):
"""Generic CaptchaAI solver — works for all supported CAPTCHA types."""
submit_data = {
"key": API_KEY,
"method": method,
"json": 1,
**params,
}
submit = requests.post("https://ocr.captchaai.com/in.php", data=submit_data, timeout=30)
data = submit.json()
if data.get("status") != 1:
raise Exception(f"Submit error: {data.get('request')}")
task_id = data["request"]
for _ in range(30):
time.sleep(5)
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY,
"action": "get",
"id": task_id,
"json": 1,
}, timeout=30).json()
if result.get("status") == 1:
return result["request"]
if result.get("request") == "ERROR_CAPTCHA_UNSOLVABLE":
raise Exception("CAPTCHA unsolvable")
raise TimeoutError("Solve timed out")
Selenium ile reCAPTCHA v2 çözme
Dört adım: sitekey'i bulun, çözün, token'ı enjekte edin, formu gönderin
Akışın özü sayfa kaynağından data-sitekey değerini çıkarmak, CaptchaAI'ye göndermek ve dönen token'ı gizli g-recaptcha-response alanına yazmaktır. Somut olarak dört işlem yaparsınız:
data-sitekeyözniteliğini regex ile yakalayın.userrecaptchamethoduyla CaptchaAI'ye gönderin.- Dönen token'ı
g-recaptcha-responsealanına yazın. - Varsa
___grecaptcha_cfgcallback'ini tetikleyin.
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import re
def solve_recaptcha_v2_selenium(driver, url):
"""Complete reCAPTCHA v2 solve in Selenium."""
driver.get(url)
# Wait for page to load
WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.TAG_NAME, "body"))
)
# Extract sitekey
page_source = driver.page_source
match = re.search(r'data-sitekey=["\']([A-Za-z0-9_-]{40})["\']', page_source)
if not match:
raise ValueError("reCAPTCHA sitekey not found")
sitekey = match.group(1)
print(f"Sitekey: {sitekey}")
# Solve via CaptchaAI
token = solve_captcha(
"userrecaptcha",
googlekey=sitekey,
pageurl=url,
)
print(f"Token received: {token[:50]}...")
# Inject token into the page
driver.execute_script(f"""
document.getElementById('g-recaptcha-response').value = '{token}';
document.getElementById('g-recaptcha-response').style.display = 'block';
""")
# If there's a callback function, call it
driver.execute_script(f"""
if (typeof ___grecaptcha_cfg !== 'undefined') {{
var clients = ___grecaptcha_cfg.clients;
for (var key in clients) {{
var client = clients[key];
if (client.rr && client.rr.l) {{
client.rr.l.callback('{token}');
}}
}}
}}
""")
# Submit the form
submit_button = driver.find_element(By.CSS_SELECTOR, "button[type='submit'], input[type='submit']")
submit_button.click()
return token
# Usage
driver = create_driver()
try:
solve_recaptcha_v2_selenium(driver, "https://staging.example.com/qa-login")
print(f"Current URL: {driver.current_url}")
finally:
driver.quit()
Birçok form yalnızca token'ı yazmakla yetinmez; ayrıca callback fonksiyonunun çağrılmasını bekler. Yukarıdaki ___grecaptcha_cfg bloğu bunu üstlenir.
Selenium ile Cloudflare Turnstile çözme
reCAPTCHA v2'den tek farkı: alan ve method adları
Turnstile'da mantık aynıdır, yalnızca token gizli cf-turnstile-response alanına yazılır ve method olarak turnstile gönderilir.
def solve_turnstile_selenium(driver, url):
"""Complete Turnstile solve in Selenium."""
driver.get(url)
WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.TAG_NAME, "body"))
)
# Extract sitekey
page_source = driver.page_source
match = re.search(r'data-sitekey=["\']([0-9x][A-Za-z0-9_-]+)["\']', page_source)
if not match:
# Try JavaScript API pattern
match = re.search(r"sitekey\s*:\s*['\"]([0-9x][A-Za-z0-9_-]+)['\"]", page_source)
if not match:
raise ValueError("Turnstile sitekey not found")
sitekey = match.group(1)
print(f"Turnstile sitekey: {sitekey}")
# Solve via CaptchaAI
token = solve_captcha(
"turnstile",
sitekey=sitekey,
pageurl=url,
)
print(f"Turnstile token: {token[:50]}...")
# Inject token
driver.execute_script(f"""
// Set the hidden input value
var inputs = document.querySelectorAll('[name="cf-turnstile-response"]');
inputs.forEach(function(input) {{ input.value = '{token}'; }});
// Also try the callback approach
if (typeof turnstile !== 'undefined' && turnstile.getResponse) {{
// Widget already rendered
}}
""")
# Submit form
submit_button = driver.find_element(By.CSS_SELECTOR, "button[type='submit'], input[type='submit']")
submit_button.click()
return token
Yani yalnızca iki şey değişir: token'ın yazıldığı gizli alan cf-turnstile-response olur ve API'ye method olarak turnstile gönderirsiniz. Sitekey çıkarımında önce data-sitekey özniteliği, bulunamazsa JavaScript API kalıbı denenir.
Selenium ile resim (OCR) CAPTCHA çözme
Klasik resim/metin CAPTCHA'ları (gördüğünüz harfleri yazın türü) için öğenin ekran görüntüsünü base64 olarak alıp CaptchaAI'ye gönderirsiniz:
import base64
def solve_image_captcha_selenium(driver, captcha_selector):
"""Solve image CAPTCHA visible in the browser."""
# Find the CAPTCHA image element
captcha_img = driver.find_element(By.CSS_SELECTOR, captcha_selector)
# Get image as base64
img_base64 = captcha_img.screenshot_as_base64
# Solve via CaptchaAI
answer = solve_captcha("base64", body=img_base64)
print(f"CAPTCHA answer: {answer}")
# Type the answer into the input field
captcha_input = driver.find_element(
By.CSS_SELECTOR, "input[name='captcha'], input[name='code'], input.captcha-input"
)
captcha_input.clear()
captcha_input.send_keys(answer)
return answer
Ekran görüntüsü boş çıkıyorsa öğe henüz görünür alanda değildir; önce scrollIntoView ile kaydırın, ardından base64 görüntüsünü alıp gönderin. Metin CAPTCHA'larında sonucu doğrudan input alanına yazarsınız — ayrı bir token enjeksiyonu gerekmez.
Selenium ile reCAPTCHA v3 çözme
reCAPTCHA v3'te görünür bir kutu yoktur; skor tabanlı çalışır. Bu yüzden version ve action parametrelerini de göndermeniz gerekir:
def solve_recaptcha_v3_selenium(driver, url, sitekey, action="verify"):
"""Solve reCAPTCHA v3 in Selenium."""
driver.get(url)
# Solve via CaptchaAI
token = solve_captcha(
"userrecaptcha",
googlekey=sitekey,
pageurl=url,
version="v3",
action=action,
)
# Inject token
driver.execute_script(f"""
// Set reCAPTCHA response
var textarea = document.getElementById('g-recaptcha-response');
if (textarea) {{
textarea.value = '{token}';
textarea.style.display = 'block';
}}
// Set any hidden input fields
var inputs = document.querySelectorAll('input[name="g-recaptcha-response"]');
inputs.forEach(function(input) {{ input.value = '{token}'; }});
""")
return token
reCAPTCHA v3 skor tabanlı çalıştığı için görünür bir kutu yoktur; token'ı enjekte ettikten sonra formu doğrudan gönderebilir, ayrı bir callback beklemezsiniz. Gönderdiğiniz action değerinin sayfadaki beklenen eylemle eşleşmesi, dönen skorun ve dolayısıyla başarı oranının artmasına yardımcı olur.
Uçtan uca otomasyon: tek sınıfta tespit-çöz-gönder
Üretimde tek tek fonksiyon çağırmak yerine türü otomatik tespit eden bir sınıf daha pratiktir. SeleniumCaptchaSolver sayfayı açar, CAPTCHA türünü belirler, uygun çözümü uygular ve formu gönderir:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import re
import time
import requests
API_KEY = "YOUR_API_KEY"
class SeleniumCaptchaSolver:
"""Complete Selenium + CaptchaAI automation class."""
def __init__(self, api_key):
self.api_key = api_key
self.driver = None
def start(self):
"""Initialize the browser."""
options = webdriver.ChromeOptions()
options.add_argument("--no-sandbox")
options.add_experimental_option("excludeSwitches", ["enable-automation"])
self.driver = webdriver.Chrome(options=options)
self.driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
"source": "Object.defineProperty(navigator, 'webdriver', {get: () => undefined})"
})
def stop(self):
"""Close the browser."""
if self.driver:
self.driver.quit()
def navigate(self, url):
"""Navigate to URL and wait for load."""
self.driver.get(url)
WebDriverWait(self.driver, 15).until(
lambda d: d.execute_script("return document.readyState") == "complete"
)
def detect_captcha(self):
"""Detect which CAPTCHA type is on the page."""
source = self.driver.page_source
if re.search(r'data-sitekey=["\'][A-Za-z0-9_-]{40}["\']', source):
if "recaptcha/api.js" in source or "grecaptcha" in source:
return "recaptcha_v2"
if "cf-turnstile" in source or "challenges.cloudflare.com/turnstile" in source:
return "turnstile"
if re.search(r'recaptcha.*v3|render=[A-Za-z0-9_-]{40}', source):
return "recaptcha_v3"
captcha_imgs = self.driver.find_elements(
By.CSS_SELECTOR, "img.captcha, img[alt*='captcha'], img[src*='captcha']"
)
if captcha_imgs:
return "image"
return None
def solve_and_submit(self, url, form_data=None):
"""Navigate, solve CAPTCHA, fill form, and submit."""
self.navigate(url)
captcha_type = self.detect_captcha()
if not captcha_type:
print("No CAPTCHA detected")
return self._fill_and_submit(form_data)
print(f"Detected: {captcha_type}")
if captcha_type == "recaptcha_v2":
self._solve_recaptcha_v2()
elif captcha_type == "turnstile":
self._solve_turnstile()
elif captcha_type == "image":
self._solve_image()
return self._fill_and_submit(form_data)
def _solve_recaptcha_v2(self):
source = self.driver.page_source
match = re.search(r'data-sitekey=["\']([A-Za-z0-9_-]{40})["\']', source)
sitekey = match.group(1)
token = self._api_solve("userrecaptcha", googlekey=sitekey, pageurl=self.driver.current_url)
self.driver.execute_script(f"""
document.getElementById('g-recaptcha-response').value = '{token}';
""")
def _solve_turnstile(self):
source = self.driver.page_source
match = re.search(r'data-sitekey=["\']([0-9x][A-Za-z0-9_-]+)["\']', source)
sitekey = match.group(1)
token = self._api_solve("turnstile", sitekey=sitekey, pageurl=self.driver.current_url)
self.driver.execute_script(f"""
document.querySelectorAll('[name="cf-turnstile-response"]')
.forEach(function(el) {{ el.value = '{token}'; }});
""")
def _solve_image(self):
img = self.driver.find_element(
By.CSS_SELECTOR, "img.captcha, img[alt*='captcha'], img[src*='captcha']"
)
answer = self._api_solve("base64", body=img.screenshot_as_base64)
captcha_input = self.driver.find_element(
By.CSS_SELECTOR, "input[name='captcha'], input[name='code']"
)
captcha_input.clear()
captcha_input.send_keys(answer)
def _fill_and_submit(self, form_data):
if form_data:
for name, value in form_data.items():
try:
field = self.driver.find_element(By.NAME, name)
field.clear()
field.send_keys(value)
except Exception:
pass
submit = self.driver.find_element(
By.CSS_SELECTOR, "button[type='submit'], input[type='submit']"
)
submit.click()
time.sleep(3)
return self.driver.current_url
def _api_solve(self, method, **params):
submit = requests.post("https://ocr.captchaai.com/in.php", data={
"key": self.api_key, "method": method, "json": 1, **params,
}, timeout=30)
data = submit.json()
if data.get("status") != 1:
raise Exception(f"Submit error: {data.get('request')}")
task_id = data["request"]
for _ in range(30):
time.sleep(5)
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": self.api_key, "action": "get", "id": task_id, "json": 1,
}, timeout=30).json()
if result.get("status") == 1:
return result["request"]
raise TimeoutError("Solve timed out")
# Usage
solver = SeleniumCaptchaSolver(API_KEY)
solver.start()
try:
result_url = solver.solve_and_submit(
"https://staging.example.com/qa-login",
form_data={"username": "user@example.com", "password": "pass123"},
)
print(f"Result: {result_url}")
finally:
solver.stop()
Sınıfın iş akışı
SeleniumCaptchaSolver tespit-çöz-gönder döngüsünü tek yerde toplar:
navigate— sayfayı açar vereadyStatetamamlanana kadar bekler.detect_captcha— sayfa kaynağını tarayıp CAPTCHA türünü döndürür.- ilgili
_solve_*— token'ı çözer ve gizli alana enjekte eder. _fill_and_submit— form alanlarını doldurup gönderir ve sonuç URL'sini döndürür.
Performans ve maliyet notları
Selenium, tarayıcı başlatma ve sayfa render'ı için istek başına 3–5 saniye ek yük getirir; CAPTCHA çözüm süresi CaptchaAI tarafında sabit kalır. Maliyeti ve gecikmeyi öngörülebilir tutmak için birkaç pratik kural:
- Paralel çözüm sayınızı plan thread'inizle eşleştirin — tek bir QA senaryosu için BASIC ($15/ay, 5 thread) genellikle yeterlidir.
- Tarayıcı örneğini yeniden kullanın; her istek için yeni bir sürücü açmayın.
- Yalnızca token'a ihtiyaç duyduğunuz adımlarda
requests'e düşün, Selenium'u yalnızca gerçek render gerektiğinde kullanın.
Sorun giderme
Aşağıdaki tablo, entegrasyonda en sık karşılaşılan beş belirtiyi olası nedeni ve pratik çözümüyle eşleştirir:
| Belirti | Olası neden | Çözüm |
|---|---|---|
| CAPTCHA tespit edildi ama token enjeksiyonu başarısız oldu | g-recaptcha-response bulunamadı |
iframe'leri kontrol edin — reCAPTCHA bir iframe içinde olabilir |
| Token enjekte edildi ama form gönderilmiyor | callback tetiklenmedi | reCAPTCHA callback fonksiyonunu açıkça çağırın |
| Site "webdriver algılandı" diyor | CDP ayarı uygulanmadı | webdriver bayrağını kaldıran CDP komutunu ekleyin |
| Resim CAPTCHA ekran görüntüsü boş çıkıyor | Öğe görünür değil | Önce öğeyi görünür alana kaydırın |
| Turnstile token'ı reddedildi | Yanlış sitekey | Canlı sayfa kaynağından sitekey'i yeniden çıkarın |
Sık sorulan sorular
Selenium mi yoksa yalnızca requests mi kullanmalıyım?
Sayfa JavaScript yürütmesi, dinamik içerik yüklemesi veya çok adımlı bir akış gerektiriyorsa Selenium kullanın. Yalnızca token'a ihtiyaç duyduğunuz basit, API tabanlı form gönderimlerinde requests daha hızlı ve hafiftir.
reCAPTCHA bir iframe içindeyse sitekey'i nasıl çıkarırım?
Önce iframe'e geçin: driver.switch_to.frame(driver.find_element(By.CSS_SELECTOR, "iframe[src*='recaptcha']")), sitekey'i okuyun, ardından driver.switch_to.default_content() ile ana içeriğe dönün. sitekey genellikle data-sitekey özniteliğinde durur.
Token'ı enjekte ettim ama form gönderilmiyor, sorun ne?
Çoğu reCAPTCHA formu, token yerleştirmenin yanında callback fonksiyonunun da çağrılmasını bekler. Yukarıdaki ___grecaptcha_cfg bloğu bunu yapar; Turnstile için de gizli cf-turnstile-response alanını doldurduktan sonra formu doğrudan gönderin.
CaptchaAI Selenium ile hangi CAPTCHA türlerini çözer?
reCAPTCHA v2/v3 (Enterprise dahil), Cloudflare Turnstile ve Challenge, GeeTest v3, BLS ve resim/grid CAPTCHA'ları desteklenir. hCaptcha ve FunCaptcha desteklenmez; CaptchaFox, Friendly Captcha ve Lemin ise beta aşamasındadır.
Selenium otomasyonu için hangi CaptchaAI planı yeterli?
Faturalama thread başına olduğu için tek seferde kaç CAPTCHA'yı paralel çözdüğünüze bağlıdır. Tek bir QA senaryosu için BASIC ($15/ay, 5 thread) genellikle yeterlidir; paralel iş yükleri büyüdükçe STANDARD ($30/ay, 15 thread) veya ADVANCE ($90/ay, 50 thread) tarafına geçebilirsiniz.
Özet
Selenium tarayıcıyı sürer, CaptchaAI CAPTCHA'yı çözer. Akış her tür için aynıdır: sayfa kaynağından türü tespit edin, CaptchaAI API'si üzerinden çözün, token'ı JavaScript ile enjekte edin ve formu gönderin. SeleniumCaptchaSolver sınıfı bu tespit-çöz-gönder döngüsünü tek yerde toplar. Kişisel veri içeren sayfaları otomatikleştiriyorsanız KVKK kapsamında yetkili bir iş akışında kaldığınızdan emin olun.