Tutorials

Cloudflare Turnstile Site Anahtarı Çıkarma ve Çözme

Bir sayfada Cloudflare Turnstile widget'ı görüyorsunuz, ama CaptchaAI'ye göndermek için gereken sitekey değerini nereden alacağınızı bilmiyorsunuz. İyi haber: bu değer her zaman sayfada, üç yerden birinde durur ve genellikle tek bir konsol komutuyla saniyeler içinde çıkar. Bu rehber, sitekey'i bulmanın üç yöntemini sırayla gösterir ve elde ettiğiniz değeri CaptchaAI API ile çalışan token'a nasıl çevireceğinizi anlatır.


Turnstile'ı çözmek için hangi iki değer yeter

CaptchaAI'nin Turnstile görevini alması için yalnızca iki parametre gerekir: widget'ın sitekey değeri ve widget'ın göründüğü sayfanın tam URL'si (pageurl). API isteğine bu ikisini method=turnstile ile birlikte gönderirsiniz, gerisini çözücü halleder. Yani asıl iş, doğru sitekey'i sayfadan güvenilir biçimde çıkarmaktır — token üretimi bundan sonra rutin bir adımdır.

sitekey, Cloudflare tarafından her Turnstile widget'ına atanan, 0x ile başlayan herkese açık bir tanımlayıcıdır. Gizli bir anahtar değildir; tarayıcının okuyabildiği her yerde durur, dolayısıyla onu almak için özel bir erişime ihtiyacınız yoktur. Değişmediği sürece aynı sitekey'i tekrar tekrar kullanabilirsiniz.


Turnstile sitekey değeri sayfada nerede durur

Turnstile sitekey değeri pratikte üç yerde görünür:

  1. .cf-turnstile öğelerindeki data-sitekey özniteliği
  2. turnstile.render() JavaScript çağrısının içinde
  3. Turnstile iframe'inin src URL'sinde

Bu üçü, sitenin widget'ı nasıl yerleştirdiğine göre değişir. Statik HTML gömen siteler birinci yolu, widget'ı JavaScript ile programlı işleyen siteler ikinci ve üçüncü yolu kullanır.


Hangi yöntemi önce denemelisiniz

Her sayfa için bu üç yöntemden en az biri sonuç verir; sıralama, en ucuzdan en güvenilire doğru gitmenizi sağlar:

Yöntem Ne zaman işe yarar Maliyet
DOM özniteliği data-sitekey ham HTML'de hazırsa En düşük — tarayıcı gerekmez
JavaScript render Widget programlı yerleştiriliyorsa Orta — regex/paket taraması
Iframe src Widget çizildikten sonra Yüksek — headless tarayıcı gerekir
  • Önce DOM özniteliği (Yöntem 1). En hızlı yol budur; JavaScript çalıştırmaya bile gerek kalmadan, tek bir requests.get ile gelen ham HTML'de data-sitekey çoğu zaman hazır durur.
  • HTML'de yoksa JavaScript render çağrısına bakın (Yöntem 2). Widget dinamik olarak yerleştiriliyorsa sitekey bir turnstile.render() çağrısının içine gömülüdür; sayfa paketini (bundle) veya oluşturulmuş HTML'i regex ile tararsınız.
  • Son çare iframe src (Yöntem 3). Widget tarayıcıda çizildikten sonra sitekey iframe URL'sine düşer; bu yüzden en güvenilir yedek yöntemdir, ancak sayfayı bir headless tarayıcıda gerçekten yüklemenizi gerektirir.

Pratik kural: statik istekle deneyin, boş dönerse headless tarayıcıya geçin.


Yöntem 1: DOM özniteliği (data-sitekey)

En doğrudan yol, tarayıcı konsolunda .cf-turnstile öğelerini sorgulamaktır:

// Browser console
document.querySelectorAll('.cf-turnstile').forEach((el, i) => {
  console.log(`Turnstile ${i}:`, {
    sitekey: el.getAttribute('data-sitekey'),
    action: el.getAttribute('data-action'),
    cData: el.getAttribute('data-cdata'),
    theme: el.getAttribute('data-theme'),
  });
});

Python ile statik HTML

Ham HTML sitekey'i zaten içeriyorsa, tarayıcı hiç açmadan doğrudan yanıt gövdesinde regex ile bulabilirsiniz:

import re
import requests

html = requests.get("https://staging.example.com/qa-login").text

matches = re.findall(
    r'class=["\'][^"\']*cf-turnstile[^"\']*["\'][^>]*data-sitekey=["\']([^"\']+)',
    html
)
for sk in matches:
    print(f"Sitekey: {sk}")

Python ile Selenium

Widget yalnızca JavaScript çalıştıktan sonra beliriyorsa, sayfayı Selenium ile yükleyip özniteliği DOM üzerinden okuyun:

from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
driver.get("https://staging.example.com/qa-login")

widgets = driver.find_elements(By.CSS_SELECTOR, ".cf-turnstile")
for w in widgets:
    sitekey = w.get_attribute("data-sitekey")
    action = w.get_attribute("data-action")
    print(f"Sitekey: {sitekey}, Action: {action}")

Yöntem 2: JavaScript render çağrısı

Bazı siteler Turnstile'ı programlı olarak işler; bu durumda sitekey, data-sitekey özniteliği yerine bir yapılandırma nesnesinin içindedir:

turnstile.render('#captcha-container', {
  sitekey: '0x4AAAAAAAB...',
  callback: function(token) {
    document.getElementById('cf-token').value = token;
  },
});

Sayfa kaynağını veya JavaScript paketini regex ile tarayarak bu çağrıdaki değeri çıkarabilirsiniz:

# Find turnstile.render calls
render_match = re.search(
    r'turnstile\.render\s*\([^,]*,\s*\{([^}]+)\}',
    html
)
if render_match:
    config = render_match.group(1)
    sk = re.search(r'sitekey\s*:\s*["\']([^"\']+)', config)
    if sk:
        print(f"Sitekey from render: {sk.group(1)}")

Puppeteer ile araya girme

sitekey çalışma zamanında hesaplanıyorsa, turnstile.render çağrısını sayfa yüklenmeden önce sarmalayıp parametreleri yakalayabilirsiniz:

// Intercept turnstile.render before page loads
await page.evaluateOnNewDocument(() => {
  window.__turnstileParams = [];
  const origRender = window.turnstile?.render;
  Object.defineProperty(window, 'turnstile', {
    set(val) {
      this._turnstile = val;
      const orig = val.render;
      val.render = function(container, params) {
        window.__turnstileParams.push(params);
        console.log('Turnstile render:', JSON.stringify(params));
        return orig.apply(this, arguments);
      };
    },
    get() { return this._turnstile; }
  });
});

await page.goto('https://staging.example.com/qa-login', { waitUntil: 'networkidle2' });

const params = await page.evaluate(() => window.__turnstileParams);
console.log('Captured Turnstile params:', params);

Yöntem 3: Iframe src

Turnstile ekranda bir iframe çizer ve sitekey bu iframe'in src adresine düşer. Diğer iki yöntem boş dönerse bu neredeyse her zaman sonuç verir:

document.querySelectorAll('iframe').forEach(iframe => {
  if (iframe.src.includes('challenges.cloudflare.com')) {
    console.log('Turnstile iframe:', iframe.src);
    const match = iframe.src.match(/sitekey=([A-Za-z0-9_-]+)/);
    if (match) console.log('Sitekey:', match[1]);
  }
});

CaptchaAI ile Turnstile'ı çözme

sitekey ve pageurl elinizde olduğunda görevi CaptchaAI'ye gönderir, ardından sonucu periyodik olarak sorgularsınız. Turnstile çözümleri genellikle 10 saniyenin altında, desteklenen türlerde yüksek başarı oranıyla tamamlanır.

İpucu: Turnstile token'larının ömrü kısadır. Token'ı üretir üretmez hedef isteğe ekleyin; uzun süre bekletirseniz süresi dolar ve yeniden çözüm gerekir.

Python

import requests
import time

API_KEY = "YOUR_API_KEY"
SITEKEY = "0x4AAAAAAAB..."
PAGE_URL = "https://staging.example.com/qa-login"

# Submit
resp = requests.post("https://ocr.captchaai.com/in.php", data={
    "key": API_KEY,
    "method": "turnstile",
    "sitekey": SITEKEY,
    "pageurl": PAGE_URL,
    "json": "1",
}).json()

if resp["status"] != 1:
    raise Exception(f"Submit error: {resp['request']}")

task_id = resp["request"]

# Poll
for _ in range(24):
    time.sleep(5)
    result = requests.get("https://ocr.captchaai.com/res.php", params={
        "key": API_KEY, "action": "get", "id": task_id, "json": "1"
    }).json()

    if result["status"] == 1:
        token = result["request"]
        print(f"Turnstile token: {token[:50]}...")
        break
    if result["request"] != "CAPCHA_NOT_READY":
        raise Exception(f"Error: {result['request']}")

JavaScript

const axios = require('axios');

const submit = await axios.post('https://ocr.captchaai.com/in.php', null, {
  params: {
    key: 'YOUR_API_KEY',
    method: 'turnstile',
    sitekey: '0x4AAAAAAAB...',
    pageurl: 'https://staging.example.com/qa-login',
    json: 1,
  }
});
const taskId = submit.data.request;

// Poll for result
let token = null;
for (let i = 0; i < 24; i++) {
  await new Promise(r => setTimeout(r, 5000));
  const poll = await axios.get('https://ocr.captchaai.com/res.php', {
    params: { key: 'YOUR_API_KEY', action: 'get', id: taskId, json: 1 }
  });
  if (poll.data.status === 1) {
    token = poll.data.request;
    break;
  }
}
console.log(`Token: ${token.substring(0, 50)}...`);

Token enjeksiyonu

CaptchaAI'den dönen token'ı, Turnstile'ın kullandığı cf-turnstile-response adlı gizli girişe yazmanız gerekir. Yalnızca girişi doldurmak çoğu zaman yetmez; widget'ın data-callback fonksiyonunu da tetiklemek daha sağlam bir sonuç verir:

# Selenium
driver.execute_script("""
    const input = document.querySelector('input[name="cf-turnstile-response"]');
    if (input) input.value = arguments[0];

    // Also set in the Turnstile widget's callback
    const widget = document.querySelector('.cf-turnstile');
    const callbackName = widget?.getAttribute('data-callback');
    if (callbackName && typeof window[callbackName] === 'function') {
        window[callbackName](arguments[0]);
    }
""", token)

Uygulamalı senaryo: staging ödeme akışının QA testi

Türkiye'deki ekiplerin en sık karşılaştığı durumu ele alalım: bir e-ticaret projesinin ödeme adımında Turnstile var ve otomatik regresyon testleriniz her koşuda bu adıma takılıyor. Çözüm, testi kendi staging.example.com/qa-login ortamınızda kurup sitekey'i bir kez çıkarmak, sonra CI hattında her testte aynı değeri pageurl ile birlikte CaptchaAI'ye göndermektir. sitekey sabit kaldığı sürece onu ortam değişkeni olarak saklar, yeniden çıkarma adımını atlarsınız.

Bu kurulumda ölçeklenmeyi thread sayısı belirler. CaptchaAI thread başına faturalandırır ve çözüm başına ücret almaz; BASIC ($15/ay, 5 thread) planı, gece çalışan bir test paketi için genellikle yeterlidir, paralel koşu sayınız arttıkça üst planlara geçersiniz. Fiyatların USD olması, TL kurundaki dalgalanmadan bağımsız öngörülebilir bir maliyet anlamına gelir — sürekli entegrasyon bütçesi planlarken pratik bir avantaj.

Bir uyarı: yalnızca yetkiniz olan, kendi sahip olduğunuz ya da test izni verilmiş sayfalarda çalışın. Topladığınız verilerde kişisel veri bulunuyorsa, bu veri KVKK kapsamına girer; CaptchaAI'yi yetkili QA ve veri toplama iş akışlarınızın içinde konumlandırın.


Sorun giderme

Sorun Sebep Düzeltme
.cf-turnstile öğesi bulunamıyor Widget dinamik olarak çiziliyor Sayfanın yüklenmesini bekleyin veya MutationObserver kullanın
sitekey boş geliyor Değer JavaScript API ile atanıyor Betiklerde turnstile.render çağrısını arayın
Token reddedildi Yanlış sitekey veya pageurl Her iki değerin de hedef sayfayla birebir eşleştiğini doğrulayın
method parametresi hatalı Turnstile için userrecaptcha kullanılmış method=turnstile değerini kullanın

Sık sorulan sorular

Turnstile sitekey değeri nasıl görünür?

0x ile başlayan, herkese açık bir dizedir (örneğin 0x4AAAAAAAB...). Gizli değildir; tarayıcının okuyabildiği DOM, betik veya iframe URL'sinde açıkça durur.

sitekey her istekte değişir mi?

Hayır. Belirli bir widget için sitekey sabittir; site sahibi Cloudflare panelinde yeni bir anahtar oluşturmadıkça değişmez. Bu yüzden onu bir kez çıkarıp ortam değişkeni olarak saklayabilirsiniz.

data-sitekey boş dönüyorsa ne yapmalıyım?

Widget muhtemelen JavaScript ile geç yerleştiriliyordur. Ham HTML yerine sayfayı Selenium veya Puppeteer ile yükleyin, ya da doğrudan iframe src'sindeki değeri okuyun (Yöntem 3).

CaptchaAI Turnstile çözümü ne kadar sürer?

Turnstile çözümleri tipik olarak 10 saniyenin altında tamamlanır ve desteklenen türlerde yüksek başarı oranı sunar. Kodda 24 kez, 5 saniye aralıkla sorgulama yapmak bu süre için güvenli bir tampon bırakır.

method parametresine ne yazmalıyım?

Turnstile için her zaman method=turnstile. reCAPTCHA için kullanılan userrecaptcha değerini Turnstile'a göndermek en sık yapılan hatadır ve token'ın reddedilmesine yol açar.


Cloudflare Turnstile CAPTCHA'larını CaptchaAI ile çözün

Ücretsiz API anahtarınızı captchaai.com üzerinden alın, yukarıdaki sitekey çıkarma yöntemlerinden birini uygulayın ve ilk Turnstile token'ınızı üretin.


İlgili kılavuzlar

Bu makale için yorumlar devre dışı bırakılmıştır.