Tutorial API

Cara Solve Cloudflare Turnstile dengan API

Cloudflare Turnstile adalah alternatif CAPTCHA yang berfokus pada privasi dan berjalan diam-diam di background. Tidak seperti CAPTCHA tradisional, Turnstile jarang menampilkan visual challenge; ia mengumpulkan sinyal browser dan menerbitkan token yang diverifikasi backend situs.

Panduan ini menunjukkan cara solve Turnstile secara programatik dengan API CaptchaAI. Jika belum membaca Quickstart CaptchaAI, mulailah dari sana untuk memahami alur 4 langkah umum.


Prasyarat

Item Nilai
API key CaptchaAI Dari dashboard di captchaai.com
Sitekey Turnstile Diekstrak dari halaman target (diawali 0x)
URL halaman URL lengkap tempat Turnstile muncul
Bahasa Python 3.7+ atau Node.js 14+

Langkah 1: Temukan sitekey Turnstile

Sitekey biasanya berada di HTML halaman, di dalam tag div atau script:

<div class="cf-turnstile" data-sitekey="0x4AAAAAAAC3DHQFLr1GavNl"></div>

Atau di-render oleh JavaScript:

turnstile.render('#widget', {
  sitekey: '0x4AAAAAAAC3DHQFLr1GavNl',
  callback: function(token) { /* ... */ }
});

Tiga cara mengekstraknya:

  1. DevTools browser — tab Elements, cari data-sitekey atau cf-turnstile.
  2. Source codeCtrl+U, lalu cari string yang diawali 0x.
  3. Tab Network — filter challenges.cloudflare.com; sitekey ada di parameter request.

Sitekey Turnstile selalu diawali 0x dan biasanya berisi 22 karakter. Ini yang membedakannya dari kunci reCAPTCHA yang diawali 6L.


Langkah 2: Kirim tugas

POST ke https://ocr.captchaai.com/in.php dengan method=turnstile:

import requests

API_KEY = "YOUR_CAPTCHAAI_KEY"
SITEKEY = "0x4AAAAAAAC3DHQFLr1GavNl"
PAGEURL = "https://staging.example.com/qa-login"

r = requests.post("https://ocr.captchaai.com/in.php", data={
    "key": API_KEY,
    "method": "turnstile",
    "sitekey": SITEKEY,
    "pageurl": PAGEURL,
    "json": 1,
})
data = r.json()
if data["status"] != 1:
    raise RuntimeError(f"submit failed: {data}")
task_id = data["request"]
print("task id:", task_id)

Padanan Node.js:

const axios = require("axios");

const { data } = await axios.post("https://ocr.captchaai.com/in.php", null, {
  params: {
    key: process.env.CAPTCHAAI_KEY,
    method: "turnstile",
    sitekey: "0x4AAAAAAAC3DHQFLr1GavNl",
    pageurl: "https://staging.example.com/qa-login",
    json: 1,
  },
});
if (data.status !== 1) throw new Error(`submit failed: ${JSON.stringify(data)}`);
const taskId = data.request;

Respon sukses: {"status": 1, "request": "<task_id>"}. Simpan task_id untuk polling.


Langkah 3: Polling hasil

Turnstile umumnya selesai dalam 10–25 detik. Tunggu 10 detik dulu, kemudian polling tiap 5 detik, maksimum 40 iterasi:

import time

time.sleep(10)
for _ in range(40):
    r = requests.get("https://ocr.captchaai.com/res.php", params={
        "key": API_KEY,
        "action": "get",
        "id": task_id,
        "json": 1,
    })
    res = r.json()
    if res["status"] == 1:
        token = res["request"]
        break
    if res["request"] != "CAPCHA_NOT_READY":
        raise RuntimeError(f"solver error: {res}")
    time.sleep(5)
else:
    raise TimeoutError("turnstile solving timed out")

print("token (60 karakter pertama):", token[:60])

Token yang dikembalikan adalah string Base64 yang biasanya diawali 0. dan berukuran 400–600 karakter.


Langkah 4: Inject Token ke Halaman

Setelah mendapat token, masukkan ke field tersembunyi cf-turnstile-response di form Turnstile, lalu submit form.

Selenium:

driver.execute_script(
    "document.querySelector('[name=cf-turnstile-response]').value = arguments[0];",
    token,
)
driver.find_element("css selector", "form").submit()

Playwright:

page.evaluate(
    "(t) => document.querySelector('[name=cf-turnstile-response]').value = t",
    token,
)
page.click("button[type=submit]")

HTTP murni: tambahkan cf-turnstile-response=<token> ke body application/x-www-form-urlencoded.

Token Turnstile berlaku sekitar 120–300 detik. Pakai segera setelah diterima, atau backend akan mengembalikan timeout-or-duplicate.


Contoh Python lengkap

import os, time, requests

API = "https://ocr.captchaai.com"
KEY = os.environ["CAPTCHAAI_KEY"]

def solve_turnstile(sitekey: str, pageurl: str) -> str:
    r = requests.post(f"{API}/in.php", data={
        "key": KEY, "method": "turnstile",
        "sitekey": sitekey, "pageurl": pageurl, "json": 1,
    }, timeout=30)
    j = r.json()
    if j["status"] != 1:
        raise RuntimeError(f"submit: {j}")
    tid = j["request"]

    time.sleep(10)
    for _ in range(40):
        r = requests.get(f"{API}/res.php", params={
            "key": KEY, "action": "get", "id": tid, "json": 1,
        }, timeout=30)
        j = r.json()
        if j["status"] == 1:
            return j["request"]
        if j["request"] != "CAPCHA_NOT_READY":
            raise RuntimeError(f"poll: {j}")
        time.sleep(5)
    raise TimeoutError("timeout")

if __name__ == "__main__":
    print(solve_turnstile("0x4AAAAAAAC3DHQFLr1GavNl", "https://staging.example.com/qa-login"))

Error Umum

Kode Arti Tindakan
ERROR_WRONG_USER_KEY Format API key salah Pastikan CAPTCHAAI_KEY lengkap
ERROR_KEY_DOES_NOT_EXIST API key tidak ditemukan Salin ulang key dari dashboard
ERROR_ZERO_BALANCE Saldo nol Top up lalu coba lagi
ERROR_PAGEURL Parameter pageurl hilang Kirim URL lengkap berawalan https://
ERROR_CAPTCHA_UNSOLVABLE Gagal setelah beberapa percobaan Pastikan sitekey dan pageurl cocok; coba lagi

Tabel error lengkap ada di panduan reCAPTCHA v2.


Saat tidak berhasil

  1. Sitekey dinamis. Beberapa situs Cloudflare menerbitkan sitekey baru tiap kunjungan; lakukan scraping ulang sebelum tiap tugas.
  2. pageurl harus persis. Backend Turnstile membandingkan URL secara ketat: kirim path eksak tanpa query string.
  3. Sidik TLS. Cloudflare bisa menolak klien berdasarkan tanda tangan TLS. Gunakan curl_cffi, Playwright, atau browser sungguhan.
  4. Token kedaluwarsa. Pakai dalam 2 menit atau harus solve ulang.
  5. Kualitas proxy. IP datacenter murah sering memicu tantangan tambahan. Pakai egress jaringan yang diotorisasi atau mobile.

Langkah selanjutnya

Komentar dinonaktifkan untuk artikel ini.