Cara Memecahkan GeeTest v3 di Python dan Mengirimkannya Kembali

solve geetest in python - How to Solve GeeTest v3 in Python and Post It Back

Sebagian besar kode CAPTCHA mengasumsikan satu token masuk, satu token keluar. GeeTest mematahkan itu. Satu pemecahan mengembalikan tiga nilai yang harus dikirimkan bersama-sama, dan tantangan yang Anda masukkan kedaluwarsa kira-kira enam puluh detik setelah Anda mengambilnya. Keduanya kerap menjebak orang, dan tak satu pun gagal dengan pesan yang membantu.

Dua input yang berperilaku berbeda

NilaiSeumur hidup
gtStatis untuk situs tersebut. Cache sesuka Anda
challengeSekali pakai, mati dalam sekitar 60 detik

Keduanya berasal dari endpoint init GeeTest milik situs itu sendiri. Nilai gt pada dasarnya adalah pengenal situs. challenge berlaku per percobaan, dan menganggapnya dapat dipakai ulang adalah alasan paling umum sebuah integrasi GeeTest berhasil saat pengujian lalu berantakan saat beban tinggi.

Penyiapan

# Python 3.10 or newer.
pip install capskip
from capskip import CapSkip

solver = CapSkip(
    host="127.0.0.1",
    port=8080,
    recaptchaTimeout=300,   # GeeTest uses this, not defaultTimeout
)

Perbedaan timeout itu mudah terlewat. defaultTimeout hanya mengatur CAPTCHA gambar; semua yang interaktif menggunakan recaptchaTimeout.

Pemecahan

result = solver.geetest(
    gt="81388ea1fc187e0c335c0a8907ff2625",
    challenge="7cf6a8b1a2c34d5e6f7089abcdef0123",
    url="https://example.com/login",
)

print(result["challenge"])
print(result["validate"])
print(result["seccode"])

Ketiga kunci itulah jawabannya. result["code"] juga terisi, tetapi untuk GeeTest isinya string JSON mentah, bukan sesuatu yang bisa Anda kirim, jadi mengambilnya karena kebiasaan menghasilkan kegagalan yang membingungkan.

Gunakan challenge yang dikembalikan, bukan yang Anda kirimkan. Keduanya tidak selalu bernilai sama.

Alur lengkap, dalam satu tempat

Pengambilan dan pemecahan harus berdampingan. Apa pun yang lambat di antaranya berisiko membuatnya kedaluwarsa:

import time
import requests
from capskip import CapSkip

solver = CapSkip()
LOGIN = "https://example.com/login"

# 1. Fresh pair, cache-busted. Cached init responses hand back dead challenges.
init = requests.get(
    "https://example.com/geetest/init",
    params={"t": int(time.time() * 1000)},
).json()

# 2. Solve immediately. Do not queue this.
result = solver.geetest(gt=init["gt"], challenge=init["challenge"], url=LOGIN)

# 3. Post all three together, alongside the real form fields.
response = requests.post(LOGIN, data={
    "geetest_challenge": result["challenge"],
    "geetest_validate": result["validate"],
    "geetest_seccode": result["seccode"],
    "username": "...",
    "password": "...",
})

Timestamp cache-busting lebih penting daripada kelihatannya. Endpoint init GeeTest sering di-cache oleh CDN atau proxy, dan respons yang di-cache memberi Anda tantangan yang sudah terpakai.

Ketiga nama field itu adalah konvensi umum GeeTest v3, tetapi sebuah situs bisa mengganti namanya. Periksa formulir aslinya sebelum berasumsi.

Mengerjakan beberapa sekaligus

Jebakan di sini adalah batching yang salah. Mengambil setumpuk challenge lalu memecahkan semuanya menjamin yang belakangan kedaluwarsa sebelum gilirannya. Ambil dan pecahkan di dalam task yang sama:

import asyncio
from capskip import AsyncCapSkip

async def solve_one(solver, url):
    init = await fetch_pair(url)          # your own fetch, awaited
    return await solver.geetest(
        gt=init["gt"], challenge=init["challenge"], url=url,
    )

async def main():
    solver = AsyncCapSkip()
    return await asyncio.gather(*[solve_one(solver, u) for u in urls])

asyncio.run(main())

Python adalah satu-satunya SDK CapSkip yang AsyncCapSkip adalah klien async yang sesungguhnya, bukan sekadar alias, sehingga ini benar-benar menjalankan pemecahan secara paralel.

Ketika gagal

from capskip import (
    ValidationException, NetworkException, ApiException, TimeoutException,
)

try:
    result = solver.geetest(gt=gt, challenge=challenge, url=page_url)
except ValidationException:
    pass   # missing gt or challenge
except NetworkException:
    pass   # CapSkip is not running
except ApiException:
    pass   # usually a challenge that expired before the solve finished
except TimeoutException:
    pass   # exceeded recaptchaTimeout

Dalam praktiknya, sebagian besar kegagalan GeeTest muncul sebagai ApiException dan berarti tantangan sudah mati. Perbaikannya adalah mengambil lebih lambat, bukan mencoba ulang dengan pasangan yang sama, karena challenge yang sudah terpakai tidak pernah valid lagi.

Pertanyaan yang sering diajukan

Mengapa result[“code”] tidak dapat digunakan?

Karena jawabannya terdiri dari tiga nilai, bukan satu. code menyimpan JSON mentahnya demi kelengkapan sementara SDK memperluas bagian yang berguna menjadi challenge, validate dan seccode. Kirimkan ketiganya.

Bisakah saya menyimpan challenge di cache antar-eksekusi?

Tidak. Token bersifat sekali pakai dan kedaluwarsa dalam sekitar satu menit. gt aman untuk di-cache; challenge tidak pernah aman.

Apakah ini mencakup GeeTest v4?

The geetest metode menargetkan v3, teka-teki geser yang dibangun di sekitar gt dan challenge pasangan. v4 mengubah model parameternya, jadi periksa versi terkini dari dokumentasi API sebelum menganggap panggilan yang sama berlaku.

Ringkasan

Ambil gt dan challenge tepat sebelum memecahkan dengan permintaan cache-busted, panggil geetest, lalu kirim challenge, validate dan seccode bersama-sama. Gunakan challenge yang dikembalikan alih-alih input Anda, dan jangan pernah mengambil challenge secara batch sebelum memecahkannya.

Bahasa lain ada di pemecah GeeTest , cakupan Python yang lebih luas ada di halaman pemecah CAPTCHA Python , dan ada puzzle langsung di halaman kami Demo GeeTest v3. CapSkip menangani bypass captcha secara lokal, sehingga volume pemecahan gratis.