Cara Memecahkan CAPTCHA dengan cURL dan HTTP API Mentah

solve captcha with curl - How to Solve CAPTCHA with cURL and the Raw HTTP API

Anda tidak memerlukan SDK. API CapSkip kompatibel dengan 2captcha, jadi Anda bisa memecahkan captcha dengan curl hanya dalam dua panggilan: kirim tugasnya lewat POST ke /in.php dan Anda mendapat sebuah ID, lalu lakukan polling ke /res.php sampai jawabannya muncul. Semuanya berjalan di 127.0.0.1:8080, jadi tidak ada endpoint jarak jauh dan tidak ada biaya per pemecahan. Panduan ini berisi parameter persis untuk setiap jenis CAPTCHA, bentuk respons JSON, dan skrip yang bisa Anda tempel langsung ke terminal.

Apa yang Anda butuhkan

  • Aplikasi CapSkip sedang berjalan, dengan layanan lokalnya sudah aktif. Pengaturan port dan kunci dibahas di panduan penyiapan.
  • curl. Ini sudah tersedia bawaan di macOS, di semua distribusi Linux, dan di Windows 10 build 1803 ke atas.
  • jq jika Anda ingin mengambil field dari respons JSON. Opsional, tetapi dengan ini contoh-contohnya cukup satu baris.

Validasi kunci mati secara bawaan, jadi string apa pun yang tidak kosong bisa dipakai sebagai key. Tetap kirim sesuatu daripada tidak sama sekali: kunci kosong akan mengembalikan ERROR_WRONG_USER_KEY.

Itu saja daftar dependensinya, karena seluruh API hanya terdiri dari dua endpoint:

Endpoint APIFungsinyaMengembalikan
/in.phpMengirim sebuah tugasID captcha berupa angka
/res.phpMenanyakan apakah ID itu sudah selesaiJawabannya, atau CAPCHA_NOT_READY

Keduanya menerima GET atau POST. POST adalah kebiasaan yang lebih baik, karena URL halaman yang berisi parameter query akan diam-diam memotong permintaan GET pada ampersand pertama yang tidak dienkode.

Langkah 1: kirim tugasnya

reCAPTCHA v2 adalah contoh yang paling singkat. Dua nilai menentukan pekerjaannya: sitekey dari halaman, dan URL halaman tempat widget itu berada.

# No install step. curl is already on your machine.
curl -X POST http://127.0.0.1:8080/in.php \
  -d "key=YOUR_API_KEY" \
  -d "method=userrecaptcha" \
  -d "googlekey=YOUR_SITEKEY" \
  -d "pageurl=https://example.com/page-with-recaptcha"

OK|2122988149   # the number after the pipe is your captcha ID

Perhatikan nama parameternya. reCAPTCHA memakai googlekey. Turnstile memakai sitekey. Mengirim sitekey ke userrecaptcha adalah penyebab paling umum munculnya respons ERROR_GOOGLEKEY .

Langkah 2: polling untuk hasilnya

Tunggu dulu, baru tanyakan. Polling seketika hanya membakar satu permintaan dan memberi Anda CAPCHA_NOT_READY.

sleep 15

curl -X POST http://127.0.0.1:8080/res.php \
  -d "key=YOUR_API_KEY" \
  -d "action=get" \
  -d "id=2122988149"

OK|03AGdBq26...   # the token, ready to inject into the form

Dua hal tentang /res.php yang sering membuat orang tersandung. Endpoint ini mengembalikan CAPCHA_NOT_READY selama tugasnya masih berjalan, dan itu bukan error, melainkan tanda untuk terus melakukan polling. Lalu setiap hasil hanya bisa dibaca satu kali, jadi simpan jawabannya begitu tiba. Pembacaan kedua atas ID yang sama akan kembali kosong.

Berapa lama menunggu sebelum polling pertama tergantung jenisnya:

TipePolling pertama setelah
Gambar1 detik
reCAPTCHA v215 hingga 20 detik
reCAPTCHA v310 hingga 15 detik
GeeTest v3sekitar 5 detik

Tambahkan json=1 agar Anda bisa mem-parsing balasannya

Format teks biasa cocok untuk orang yang membaca terminal dan merepotkan untuk skrip. Tambahkan json=1 ke salah satu endpoint dan Anda akan mendapatkan objek yang stabil sebagai gantinya.

// in.php with json=1
{"status": 1, "request": "2122988149"}

// res.php with json=1, once it is solved
{"status": 1, "request": "03AGdBq26..."}

// res.php with json=1, still working
{"status": 0, "request": "CAPCHA_NOT_READY"}

status bernilai 1 untuk sukses dan 0 untuk selain itu, dan nilai yang menarik selalu berada di request. Dengan begitu semuanya menjadi dua ekspresi jq .

Semua metode dalam satu tabel

Sembilan jenis CAPTCHA, lima nilai method. Variannya berupa parameter tambahan, bukan endpoint baru.

TipemethodParameter wajib
Gambar, file yang diunggahpostfile
Gambar, base64base64body
reCAPTCHA v2userrecaptchagooglekey, pageurl
reCAPTCHA v2 Invisibleuserrecaptchaplus invisible=1
reCAPTCHA Enterpriseuserrecaptchaplus enterprise=1
reCAPTCHA v3userrecaptchaplus version=v3, action
Widget Turnstileturnstilesitekey, pageurl
Halaman challenge Turnstileturnstileplus data, pagedata
GeeTest v3geetestgt, challenge, pageurl

Sebuah gambar dikirim sebagai unggahan form atau sebagai base64 di dalam body:

# File upload. Note the @ in front of the path. Use -F for every
# field here: curl refuses to mix -F and -d in one request.
curl -X POST http://127.0.0.1:8080/in.php \
  -F "key=YOUR_API_KEY" -F "method=post" -F "[email protected]"

# Or send the bytes inline, already base64 encoded.
curl -X POST http://127.0.0.1:8080/in.php \
  -d "key=YOUR_API_KEY" \
  -d "method=base64" \
  --data-urlencode "body=$(base64 < captcha.png | tr -d '\n')"

Gunakan --data-urlencode untuk apa pun yang mengandung +, / atau =. Payload base64 mengandung ketiganya, dan -d biasa akan merusaknya.

Turnstile juga mengembalikan user agent

Cloudflare mengikat token ke sidik jari browser yang menghasilkannya, jadi mengirim token dari user agent yang berbeda akan membuatnya ditolak meskipun tokennya sendiri valid. API mentah memberi Anda user agent yang dipakai, di dua tempat:

  • Dengan json=1, sebagai field userAgent pada respons.
  • Dalam mode teks biasa, sebagai header respons X-Turnstile-User-Agent header respons.
# -i prints the headers, which is where the user agent lives
# when you are not using json=1.
curl -i -X POST http://127.0.0.1:8080/res.php \
  -d "key=YOUR_API_KEY" -d "action=get" -d "id=2122988149"

X-Turnstile-User-Agent: Mozilla/5.0 ...
OK|0.abc123...

Challenge satu halaman penuh juga membutuhkan data (nilai cData) dan pagedata (chlPageData) yang diambil dari halaman tepat sebelum Anda mengirim. Mode widget tidak membutuhkan keduanya. Halaman pemecah Turnstile membahas perbedaannya lebih rinci.

Jawaban GeeTest terdiri dari tiga field, bukan satu

GeeTest tidak mengembalikan satu token. Minta JSON dan Anda akan mendapatkan tiga nilai yang akan dikirim balik oleh front end situs itu sendiri.

{
  "status": 1,
  "request": {
    "geetest_challenge": "...",
    "geetest_validate":  "...",
    "geetest_seccode":   "..."
  }
}

The gt nilainya statis per situs. challenge bersifat sekali pakai dan mati dalam waktu sekitar satu menit, jadi ambil nilainya tepat sebelum Anda mengirim, jangan di awal skrip yang panjang.

Mengarahkan pemecahan melalui proxy

Dua parameter, ditambahkan ke panggilan /in.php yang sama:

curl -X POST http://127.0.0.1:8080/in.php \
  -d "key=YOUR_API_KEY" \
  -d "method=userrecaptcha" \
  -d "googlekey=YOUR_SITEKEY" \
  -d "pageurl=https://example.com/page-with-recaptcha" \
  -d "proxy=login:[email protected]:3128" \
  -d "proxytype=HTTPS"

proxytype menerima HTTP, HTTPS, SOCKS5 atau SOCKS5H. Proxy hanya berlaku untuk reCAPTCHA, Turnstile dan GeeTest. Pemecahan gambar membaca piksel yang sudah Anda miliki dan tidak pernah menyentuh situs target, jadi proxy di sana tidak berpengaruh.

Skrip lengkap

Kirim, polling dengan batas atas, cetak tokennya. Sekitar dua puluh baris, tanpa dependensi selain curl.

#!/usr/bin/env bash
set -euo pipefail

API="http://127.0.0.1:8080"
KEY="YOUR_API_KEY"

# Submit and keep only the part after the pipe.
ID=$(curl -s -X POST "$API/in.php" \
  -d "key=$KEY" -d "method=userrecaptcha" \
  -d "googlekey=YOUR_SITEKEY" \
  -d "pageurl=https://example.com/page-with-recaptcha" | cut -d'|' -f2)

sleep 15

# Poll every 5s, give up after 20 tries so this cannot hang forever.
for _ in $(seq 20); do
  R=$(curl -s -X POST "$API/res.php" -d "key=$KEY" -d "action=get" -d "id=$ID")
  [ "$R" = "CAPCHA_NOT_READY" ] || { echo "${R#OK|}"; exit 0; }
  sleep 5
done

echo "timed out waiting for $ID" >&2; exit 1

The || { ...; exit 0; } adalah cabang yang aktif untuk apa pun yang bukan CAPCHA_NOT_READY, termasuk kode error. Itu memang disengaja: error berarti berhenti, bukan terus melakukan polling.

Error yang akan Anda temui di lapisan ini

KodeBerartiPerbaiki
ERROR_WRONG_USER_KEYKunci tidak ada atau kosongKirim string apa pun yang tidak kosong sebagai key
ERROR_WRONG_METHODNilai salah untuk method atau actionPeriksa ejaannya terhadap tabel di atas
ERROR_BAD_PARAMETERSParameter wajib tidak adaBandingkan dengan kolom parameter wajib di atas
ERROR_GOOGLEKEYThe googlekey nilainya ditolakAnda mungkin mengirim sitekey sebagai gantinya
ERROR_PAGEURLThe pageurl nilainya ditolakSertakan skemanya, dan gunakan POST alih-alih GET
CAPCHA_NOT_READYMasih diprosesBukan error. Lanjutkan polling ID yang sama
Respons kosongSudah dibaca, atau ID tersebut tidak adaHasil hanya bisa dibaca sekali. Simpan yang pertama

Rumusan persis setiap kode yang bisa dikembalikan API ada di dokumentasi API.

Kapan sebaiknya berhenti memakai curl

HTTP mentah sangat cocok untuk uji cepat, pipeline shell, atau bahasa yang tidak punya klien resmi. Untuk kode aplikasi, CapSkip SDKs sepadan dengan tambahan dependensi terutama karena satu alasan: mereka tidak melakukan polling dengan interval tetap. Mereka mulai dari 250 md lalu melonggar hingga pollingInterval, sehingga sebuah pemecahan biasanya kembali lebih cepat daripada loop buatan tangan di atas, yang setiap kali menunggu penuh 15 detik.

SDK juga mengubah string error menjadi exception bertipe, serta menangani user agent Turnstile dan jawaban tiga field GeeTest untuk Anda. Klien resmi tersedia untuk Python, Node.js, PHP dan .NET.

Pertanyaan yang sering diajukan

Bisakah saya memakai GET alih-alih POST?

Bisa, kedua endpoint menerimanya. Masalahnya, pageurl yang mengandung query string sendiri akan terpotong pada ampersand pertama yang tidak dienkode, dan Anda akan mendapatkan ERROR_PAGEURL atau pemecahan terhadap halaman yang keliru. Jika Anda harus memakai GET, lewatkan dulu URL-nya melalui --data-urlencode terlebih dahulu.

Kunci API apa yang harus saya kirim?

String apa pun yang tidak kosong. Validasi kunci mati secara bawaan karena layanannya hanya mendengarkan di localhost, jadi key=capskip berfungsi dengan baik. Kuncinya tetap harus ada: jika dihilangkan, Anda akan mendapatkan ERROR_WRONG_USER_KEY alih-alih hasil pemecahan.

Apakah ini berfungsi dari Windows PowerShell?

Gunakan curl.exe secara eksplisit. Di PowerShell, curl adalah alias untuk Invoke-WebRequest, yang tidak memahami -d dan akan melemparkan error parameter yang tampak seperti masalah API. Menulis curl.exe akan melewati alias tersebut.

Bisakah saya menjalankan beberapa pemecahan sekaligus?

Bisa. Kirim sebanyak apa pun tugas yang Anda mau dan lakukan polling setiap ID secara terpisah. Tidak ada yang membuatnya berurutan dan tidak ada kuota per menit, karena pekerjaannya terjadi di perangkat keras Anda sendiri, bukan di antrean bersama.

Ringkasan

Kirim tugasnya lewat POST ke /in.php, simpan ID-nya, tunggu jeda yang sesuai dengan jenisnya, lalu lakukan polling ke /res.php sampai Anda mendapat sesuatu selain CAPCHA_NOT_READY. Tambahkan json=1 jika balasannya dibaca oleh sebuah skrip. Waspadai dua jebakan penamaan: googlekey untuk reCAPTCHA versus sitekey untuk Turnstile, serta fakta bahwa sebuah hasil hanya bisa dibaca satu kali.

Karena ini adalah pemecah captcha yang berjalan di komputer Anda sendiri, loop di atas tidak punya kuota yang harus dipatuhi dan tidak ada saldo yang harus diisi ulang. Arahkan ke localhost, dan satu-satunya batas adalah seberapa cepat CPU Anda menyelesaikan antreannya.