hCaptcha di Python dengan SDK CapSkip: Satu Panggilan, Satu Token

hcaptcha in python - hCaptcha in Python with the CapSkip SDK: One Call, One Token

Untuk memecahkan hCaptcha di Python dengan SDK CapSkip, panggil solver.hcaptcha() dengan sitekey widget dan alamat halaman, lalu kirim formulir Anda dengan token yang dikembalikan dan User-Agent yang dilaporkannya. SDK mengirim task, melakukan polling untuk hasilnya, lalu mengembalikan kedua nilai itu, sehingga skrip sebagian besar berisi aturan percobaan ulang dan POST formulir. Yang bekerja di baliknya adalah pemecah hCaptcha CapSkip. Pemecah ini berjalan di PC Windows Anda sendiri dengan lisensi tetap, jadi mengganti token yang kedaluwarsa atau ditolak tidak dikenai biaya.

Apa yang Anda butuhkan

  • PC Windows yang menjalankan CapSkip 4.0.0 atau lebih baru. Rilis itu, dari 3 November 2026, menambahkan pemecahan hCaptcha, termasuk Enterprise. Instal dengan mengikuti panduan penyiapan.
  • Python 3.10 atau lebih baru, yaitu batas minimum yang dinyatakan paket capskip, dan dua paket: capskip 1.6.0 atau lebih baru, versi pertama dengan metode hCaptcha, dan requests. Diuji dengan capskip 1.6.0 dan requests 2.34.2 pada Python 3.11.7 dan 3.14.0, dan tidak pada versi lain.
  • Prompt PowerShell, tempat Anda menjalankan pip install capskip requests.
  • Halaman dengan widget hCaptcha yang Anda miliki atau boleh Anda otomatisasi, beserta sitekey-nya. Langkah 2 menunjukkan tempat menemukannya.
  • Sebuah alamat untuk CapSkip. Tempat skrip berjalan menentukan modenya. Mode Local (127.0.0.1) hanya melayani PC tempat CapSkip berada. Mode Server juga mendengarkan di jaringan atau IP publik Anda, sehingga PC lain, Windows VPS, atau platform hosting dapat mengirim permintaan yang sama. Anda beralih mode di pengaturan koneksi. Kode di bawah mengharapkan format CapSkip default, jadi biarkan setiap pengaturan Service Emulator pada nilai defaultnya.
  • Opsional: sebuah proxy. Langkah 2 menjelaskan tempat memasangnya.

Cara pengujiannya: terhadap dua server mock (server pengganti yang dibuat khusus untuk pengujian) yang saya tulis, bukan terhadap aplikasi CapSkip yang asli atau situs hCaptcha sungguhan. Satu mock meniru pemeriksaan CapSkip di bagian hCaptcha pada Dokumentasi API. Mock lainnya berperan sebagai formulir pendaftaran dan sekaligus bertindak sebagai forward proxy. Tidak ada hal di sini yang mengukur waktu pemecahan sungguhan, dan aturan situs di mock (token sekali pakai, User-Agent yang cocok, masa berlaku dua menit) berasal dari dokumentasi CapSkip, bukan dari hCaptcha. Pemeriksaan sesungguhnya dilakukan oleh situs yang Anda tuju. Untuk cara kerjanya, lihat dokumentasi developer.

Langkah 1: buat solver

Keempat blok kode di bawah berada dalam satu file, secara berurutan. Beri nama hcaptcha_demo.py. Tidak ada yang berjalan sampai blok terakhir terpasang. SDK pada eksekusi ini adalah capskip 1.6.0 yang asli, dan hanya aplikasi CapSkip di baliknya yang berupa mock. Argumen apiKey pada constructor secara default berisi string capskip, yang berfungsi selama API Key Validation nonaktif. Jika Anda mengaktifkan validasi, berikan key Anda sebagai apiKey.

Constructor juga menentukan berapa lama SDK menunggu hCaptcha. Argumen recaptchaTimeout, 300 detik secara default, berlaku karena widget dilewati di browser sungguhan. Kode menurunkannya menjadi 180 detik, itu pilihan saya dan bukan pengaturan CapSkip. Batas itu hanya mencakup polling. SDK tidak menetapkan timeout pada panggilan HTTP-nya sendiri, dan terhadap mock, balasan yang ditahan selama 20 detik membuat panggilan menunggu penuh 20 detik walaupun recaptchaTimeout bernilai 5. Masalah muncul sebagai exception yang Anda impor dari capskip: ValidationException ketika SDK menolak argumen Anda sebelum mengirim apa pun, ApiException untuk kode error CapSkip, TimeoutException ketika waktu tunggu habis, dan NetworkException ketika CapSkip tidak dapat dijangkau.

# pip install capskip requests
import re

import requests
from capskip import ApiException, CapSkip

PAGE_URL = "https://example.com/signup"  # the page that shows the widget
SITEKEY = "YOUR_SITEKEY"  # the data-sitekey of its h-captcha div

# Local mode. In Server mode, use your server's address as the host.
# With API Key Validation on, also pass apiKey="YOUR_API_KEY".
solver = CapSkip(host="127.0.0.1", port=8080, recaptchaTimeout=180)

Langkah 2: minta token dari CapSkip

Sitekey bersifat publik dan sama untuk setiap pengunjung. Sebagian besar halaman mencantumkannya pada container widget sebagai data-sitekey. Halaman yang membangun widget dengan skrip meneruskannya sebagai opsi sitekey dari hcaptcha.render(), dan alamat iframe hCaptcha membawanya sebagai sitekey=. Isi SITEKEY dengan nilainya, dan isi PAGE_URL dengan alamat lengkap halaman yang menampilkan widget.

Panggilannya adalah solver.hcaptcha(SITEKEY, PAGE_URL). Panggilan ini mengirim task dan melakukan polling sampai token siap, jadi Anda tidak memegang ID task dan tidak menulis loop. Dokumentasi API mentah menyarankan menunggu 10 detik dulu, tetapi SDK melakukan polling seketika, lalu tidur 0.25 detik dan menggandakannya setiap kali jawabannya belum siap, hingga 5 detik. Menurut dokumentasi, satu pemecahan biasanya memakan 10 sampai 30 detik. Saya tidak pernah mengukur yang sungguhan.

Hasilnya berupa dictionary. Field token dan code berisi string yang sama, yaitu untuk h-captcha-response, dan userAgent adalah User-Agent yang memperolehnya. Field respKey adalah nilai kedua yang diberikan hCaptcha kepada widget. Field ini selalu ada, kosong jika tidak ada nilainya, dan dokumentasi menyebut sebagian besar situs tidak pernah membacanya, jadi kode mengabaikannya. Setiap hasil diberikan sekali saja dan SDK membacanya untuk Anda, sehingga fungsi mengembalikan token dan User-Agent bersama-sama. Dokumentasi menyebut CapSkip memakai argumen userAgent hanya jika cocok dengan browser yang dipakainya untuk memecahkan, jadi contoh ini membiarkan CapSkip yang memilih.

Proxy bersifat opsional untuk metode ini. Dokumentasi menyebut satu alamat IP sudah cukup untuk pengujian, dan bahwa aliran pemecahan yang stabil dari satu IP adalah hal yang ditangkap oleh rate limit hCaptcha. Untuk volume besar, muat daftar proxy di pengaturan hCaptcha atau kirim proxy bersama setiap task. Proxy pada task diutamakan daripada daftar. Fungsi menerima proxy sebagai URL lengkap seperti http://user:[email protected]:8080 dan mengirim skemanya sebagai proxytype dan sisanya sebagai field proxy. Untuk HTTP dan HTTPS, proxy berfungsi apa adanya. Untuk proxy SOCKS, jalankan pip install requests[socks] terlebih dahulu. Jika Anda merotasi proxy, lihat panduan rotasi proxy untuk caranya.

def solve(proxy=None):
    options = {}
    if proxy:  # for example http://user:[email protected]:8080
        scheme, address = proxy.split("://", 1)
        # The SDK sends type as proxytype and uri as proxy.
        options["proxy"] = {"type": scheme.upper(), "uri": address}
    result = solver.hcaptcha(SITEKEY, PAGE_URL, **options)
    return result["token"], result["userAgent"]  # delivered once: keep both

Langkah 3: kirim formulir dengan User-Agent yang sama

Di browser, widget menulis token ke textarea tersembunyi bernama h-captcha-response, dengan salinan bernama g-recaptcha-response. Tanpa browser, Anda mengirim h-captcha-response sendiri, dan g-recaptcha-response juga jika formulir memilikinya. Kode di bawah mengirim keduanya. Field formulir Anda sendiri ikut dikirim bersamanya, dan namanya mengikuti yang dipakai situs. POST dikirim ke PAGE_URL, jadi jika action formulir menunjuk ke alamat lain, ubah argumen pertama panggilan post, yaitu PAGE_URL.

User-Agent itu penting. Balasan menyebut browser yang memperoleh token, dan dokumentasi meminta Anda mengirim formulir dengan string yang sama. Karena itu fungsi mengaturnya pada session sebelum halaman dimuat, sehingga pemuatan halaman dan POST membawa User-Agent yang sama. Token hanya sekali pakai dan kedaluwarsa sekitar dua menit setelah diterbitkan, jadi kirim segera dan minta token baru pada setiap percobaan.

POST juga menyertakan halaman asalnya sebagai Referer, karena requests tidak mengirim header Referer maupun Origin dengan sendirinya. Sebagian framework menolak POST formulir HTTPS yang tidak memiliki keduanya. Sebagai contoh, dalam dokumentasi Django CSRF, dijelaskan pemeriksaan referer yang ketat untuk permintaan HTTPS yang datang tanpa header Origin.

def submit_form(session, token, user_agent, email):
    # Every request from here on carries the User-Agent the token was
    # earned with, the page load included.
    session.headers["User-Agent"] = user_agent
    session.get(PAGE_URL, timeout=30)  # picks up the page's own cookies
    return session.post(
        PAGE_URL,
        data={
            "email": email,  # your form's own fields go here
            "h-captcha-response": token,
            "g-recaptcha-response": token,  # the widget fills both
        },
        headers={"Referer": PAGE_URL},  # requests sends no Referer by itself
        timeout=30,
    )

Langkah 4: contoh lengkap dengan aturan percobaan ulang

Blok terakhir menyatukan langkah-langkah menjadi satu skrip. Tambahkan di akhir hcaptcha_demo.py, pastikan PAGE_URL dan SITEKEY di bagian atas adalah milik Anda, lalu jalankan python hcaptcha_demo.py dari folder yang berisi file itu (py hcaptcha_demo.py berfungsi jika python tidak ada di PATH Anda). Skrip melakukan hingga tiga percobaan.

Kode error menentukan apa yang mendapat percobaan lagi. Dokumentasi menyebut ERROR_CAPTCHA_UNSOLVABLE berarti task gagal dan task baru harus dikirim, jadi itu satu-satunya kode dalam set percobaan ulang. Dua kegagalan lain menyebut penyebabnya karena pengiriman ulang akan gagal dengan cara yang sama: sitekey yang ditolak hCaptcha untuk halaman itu dan proxy yang tidak dapat dijangkau. Kode lain dalam tabel Kesalahan umum menunjuk ke permintaan atau penyiapan. SDK memasukkan kode itu ke dalam pesan ApiException, sebagai teks polos atau dalam amplop JSON kecil, sehingga error_code mengambil kata ERROR_ dan berfungsi pada keduanya. Semua yang lain menghentikan skrip seketika, termasuk ketiga exception yang tidak ditangkap loop: ValidationException, TimeoutException, dan NetworkException.

Formulir yang ditolak oleh server situs mendapat token baru dan percobaan lagi. Jika tiga token gagal dengan cara yang sama, periksa field formulir. HTTP 400 karena field yang hilang akan terulang sebaik apa pun tokennya. Selain itu, reply.ok hanya berarti statusnya di bawah 400. Banyak situs menjawab 200 dan menampilkan pesan error di halaman, jadi ganti pengujian itu dengan pemeriksaan sesuatu yang hanya ditampilkan situs Anda saat berhasil.

# Only a task CapSkip could not solve gets another try. A bad sitekey, a
# dead proxy or a wrong key would fail the same way again.
RETRY = {"ERROR_CAPTCHA_UNSOLVABLE"}


def error_code(err):
    # The message holds the code as bare text or inside a JSON envelope.
    found = re.search(r"ERROR_[A-Z_]+", str(err))
    return found.group(0) if found else str(err)


def sign_up(email, proxy=None):
    session = requests.Session()
    if proxy:
        session.proxies = {"http": proxy, "https": proxy}
    for attempt in range(1, 4):
        try:
            token, user_agent = solve(proxy)
        except ApiException as err:
            code = error_code(err)
            if code not in RETRY:
                raise
            print(f"attempt {attempt}: {code}, new task")
            continue
        reply = submit_form(session, token, user_agent, email)
        if reply.ok:
            return reply
        print(f"attempt {attempt}: the site answered {reply.status_code}, new token")
    raise RuntimeError("no accepted form after 3 attempts")


if __name__ == "__main__":
    reply = sign_up("[email protected]")
    print(reply.status_code, reply.text[:60])

Pada eksekusi mock, skrip berperilaku seperti ini, dengan hasil yang sama pada Python 3.11.7 dan 3.14.0:

Pengaturan mockYang dilakukan skrip
Token siap pada polling keduaSatu task, lalu formulir diterima dengan status 200
Dua pemecahan pertama ditolakDua baris percobaan, lalu status 200 pada task ketiga
Situs menjawab 403 pada POST formulir pertamaSatu baris percobaan, task kedua dengan token baru, lalu status 200
ERROR_PROXY_CONNECT_REFUSED pada pollingDimunculkan setelah satu task, tanpa percobaan ulang
Error dikirim sebagai teks polos, bukan JSONPerilaku yang sama seperti dengan JSON, termasuk percobaan ulang
URL proxy diteruskan ke sign_upin.php menerima proxy dengan proxytype HTTP, dan pemuatan halaman serta POST formulir sama-sama melewati mock proxy
Token dikirim dengan User-Agent requests defaultSitus mock menjawab 403
Token yang sama dikirim dua kaliPOST kedua mendapat 403
CapSkip tidak pernah siap, recaptchaTimeout diturunkan menjadi 25 detikTimeoutException sekitar 28 detik setelah panggilan, karena tidur terakhir di antara polling adalah 5 detik

Anggap baris-baris situs sebagai pengujian terhadap mock saya sendiri. Aturannya mengikuti dokumentasi CapSkip, kecuali bahwa saya menambahkan pemeriksaan cookie session dan syarat bahwa kedua field token harus cocok. Baris-baris itu tidak membuktikan apa pun tentang hCaptcha atau situs sungguhan.

Kesalahan umum

KesalahanPenyebabPerbaiki
ValidationExceptionSDK menolak panggilan sebelum mengirimnya: sitekey kosong, alamat halaman yang bukan URL http atau https lengkap, nilai invisible selain 0, 1, true, atau false, tipe proxy yang tidak didukung, atau opsi yang tidak diterima API hCaptcha CapSkip, seperti domain milik 2CaptchaBaca pesannya, yang menyebut masalahnya, lalu perbaiki argumennya
ERROR_RECAPTCHA_INVALID_SITEKEYhCaptcha menolak sitekey untuk halaman itu. Sitekey kosong tidak pernah sampai sejauh ini, karena SDK menolaknya lebih duluSalin ulang data-sitekey dari halaman dan periksa bahwa PAGE_URL adalah halaman yang menampilkan widget
ERROR_CAPTCHA_UNSOLVABLEhCaptcha tidak berhasil dilewatiKirim task baru. Loop melakukannya hingga tiga kali
ERROR_PROXY_FORMATCapSkip tidak bisa membaca nilai proxyPeriksa nilai proxy. CapSkip membaca IP:PORT, LOGIN:PASSWORD@IP:PORT, dan IP:PORT:LOGIN:PASSWORD, dan skrip ini memecah URL seperti http://user:pass@IP:PORT menjadi proxytype dan alamat setelah skemanya
ERROR_PROXY_CONNECT_REFUSEDTarget tidak dapat dijangkau melalui proxy. Saya hanya bisa mensimulasikannyaUji proxy secara terpisah, lalu periksa kembali tipe dan login-nya
ERROR_TASK_NOT_SUPPORTEDCapSkip ini tidak menerima tipe task tersebut. Kemungkinan penyebabnya adalah versi yang lebih lama dari 4.0.0, atau Service Emulator yang diatur ke layanan yang menolak hCaptchaPerbarui CapSkip ke 4.0.0 atau lebih baru dan biarkan Service Emulator pada nilai defaultnya
ERROR_WRONG_USER_KEY atau ERROR_KEY_DOES_NOT_EXISTKey salah sementara API Key Validation aktif. SDK mengirim string capskip kecuali Anda memberikan apiKeyBerikan key Anda sebagai argumen apiKey pada CapSkip()
TimeoutExceptionTidak ada token setelah menunggu 180 detik yang ditetapkan recaptchaTimeout di Langkah 1, atau CapSkip berhenti menjawab saat SDK melakukan polling, yang dianggap SDK sebagai belum siap. Ini tidak termasuk dalam set percobaan ulangBuka CapSkip, lihat Monitor untuk task itu, lalu jalankan skrip lagi
NetworkExceptionTidak ada yang mendengarkan di host dan port yang Anda berikan ke CapSkip(), atau CapSkip menjawab dengan status error HTTPJalankan CapSkip, lalu bandingkan host dan port dengan pengaturan koneksi
Situs menolak token yang tampak validToken sudah pernah dipakai, lebih tua dari sekitar dua menit, datang dengan User-Agent lain, atau POST tidak membawa Referer. Tiga penyebab pertama berasal dari dokumentasi CapSkipKirim setiap token sekali saja, segera, dengan User-Agent dari balasan yang sama, dan dengan halaman sebagai Referer

Jika situs tetap menolak token

Beberapa situs, terutama yang memakai hCaptcha Enterprise, menolak token yang dinilai hCaptcha berisiko meskipun widget berhasil dilewati. Dokumentasi CapSkip menyebutnya sitekey ketat. Dokumentasi menyarankan High score mode untuk hCaptcha, di Settings, Captcha types, hCaptcha. Mode ini memerlukan Google Chrome terinstal di PC yang menjalankan CapSkip. Changelog 4.0.0 menyebut mode ini aktif secara default, dan bahwa hCaptcha dipecahkan di CapSkip Custom Browser ketika mode ini nonaktif atau Chrome tidak ada. Dokumentasi juga meminta proxy yang baik, dan agar formulir dikirim dari alamat yang sama dengan User-Agent dalam balasan. Saya tidak bisa menguji semua ini tanpa situs ketat yang sungguhan, jadi anggap ini sebagai panduan dari dokumentasi CapSkip, bukan sesuatu yang saya verifikasi.

Menggunakan CapSkip di server dari skrip Anda

Satu-satunya yang diperlukan skrip dari CapSkip adalah host dan port. Dalam mode Server, CapSkip juga menerima koneksi dari perangkat lain di jaringan Anda, atau dari internet di Windows VPS, dan panduan penyiapan menyarankan IP publik statis untuk akses yang stabil. Mode Server mengharuskan CapSkip berjalan sebagai administrator. Berikan alamat dan port server ke CapSkip() dan tidak ada hal lain di skrip yang berubah. Kepemilikan dan penagihan juga tidak berubah: mesin itu milik Anda dan tidak ada yang diukur. Namun itu membiarkan port terbuka bagi alamat lain, jadi buat aturan blokir Windows Firewall untuk alamat yang tidak Anda percayai.

Pemecahan kini berjalan di server. Untuk sitekey ketat, dokumentasi meminta alamat yang sama di kedua sisi, jadi berikan proxy pada argumen proxy milik sign_up dan proxy itu dipakai untuk task maupun session Anda.

FAQ

Bisakah saya memakai klien async?

Bisa. AsyncCapSkip menerima argumen constructor yang sama, dan menjalankan await pada metode hcaptcha()-nya dengan sitekey dan alamat halaman yang sama mengembalikan dictionary yang sama. Klien ini memakai httpx, yang diinstal pip bersama capskip. Saya hanya menjalankannya terhadap mock.

Bisakah saya memanggil CapSkip dari platform hosting?

Bisa, melalui mode Server. Jalankan CapSkip di mesin Windows dengan alamat yang dapat dijangkau, berikan alamat itu ke CapSkip(), dan panggilannya sama. Pemecahnya tetap berada di perangkat keras yang Anda kendalikan, dan platform hanya mengirim permintaan HTTP ke sana.

Bagaimana dengan widget invisible dan Enterprise?

Keduanya memakai metode hcaptcha() yang sama. Widget invisible memiliki atribut data-size yang diatur ke invisible, jadi berikan invisible=True. Untuk situs Enterprise yang mengatur nilai rqdata, berikan sebagai data, dan ambil yang baru untuk setiap task. Terhadap mock, in.php menerima invisible=1 dan nilai data pada kedua kasus. Saya tidak menjalankan keduanya di situs sungguhan.

Versi singkatnya

Memecahkan hCaptcha di Python berpusat pada satu panggilan hcaptcha() dan POST formulir dengan User-Agent yang memperoleh token. Coba ulang hanya ketika CapSkip tidak dapat memecahkan task, dan biarkan setiap error lain menghentikan skrip. Karena CapSkip adalah pemecah captcha lokal dengan lisensi tetap, mencoba ulang token yang ditolak hanya soal menjalankan loop lagi. Halaman pemecah CAPTCHA Python memuat panggilan SDK untuk tipe lainnya, dan Anda bisa melihat widget lolos di Demo hCaptcha.