Cara Memecahkan CAPTCHA di Task Huey dengan SQLite pada Windows

huey captcha - How to Solve CAPTCHAs in Huey Tasks With SQLite on Windows

Untuk memecahkan CAPTCHA di Huey, simpan queue di file SqliteHuey di samping modul task Anda, panggil CapSkip di dalam task yang memiliki percobaan ulang, dan jalankan consumer dengan worker thread. Di Windows, itulah seluruh stack-nya: satu file SQLite, tanpa server Redis, dan pemecah CAPTCHA di PC yang sama. Penyiapan huey captcha ini memiliki empat jebakan, dan panduan ini membahas setiap jebakan itu. Consumer-nya berupa exe, bukan huey_consumer.py. Opsi timeout milik Huey tidak berpengaruh apa pun pada worker thread, sehingga satu pemecahan yang macet menahan satu worker selamanya. Dengan nilai default, membaca hasil melaporkan percobaan pertama yang gagal sementara Huey masih mencoba ulang. Selain itu, CancelExecution menerima retry sebagai argumen pertamanya, sehingga cara yang paling jelas untuk menghentikan percobaan ulang justru bisa terus mencoba ulang tanpa henti.

Apa yang Anda butuhkan

  • CapSkip yang berjalan di komputer Windows, dengan solver reCAPTCHA diaktifkan.
  • Python 3.10 atau lebih baru, versi minimum SDK CapSkip. Huey 3.4.0 tidak menyatakan versi minimum sendiri. Semua yang ada di bawah sudah dijalankan di Python 3.13.7 dan 3.14.0 dengan huey 3.4.0 dan capskip 1.3.0.
  • Tanpa Redis. SqliteHuey menyimpan queue, jadwal, lock, dan hasil dalam satu file SQLite.
  • Sebuah alamat untuk pemecah CAPTCHA. Dalam mode Local, CapSkip menjawab di 127.0.0.1 hanya untuk perangkat itu. Dalam mode Server, CapSkip mendengarkan di alamat jaringan atau IP publik Anda, sehingga consumer di mesin lain dapat memanggilnya melalui API. Keduanya diatur di pengaturan koneksi.

Langkah 1: instal Huey dan SDK CapSkip

Buat virtual environment di folder proyek Anda dan instal tiga paket. Paket requests dipakai oleh contoh lengkap untuk mengambil halaman login dan mengirim form-nya, serta oleh perbaikan timeout di bagian selanjutnya.

# Windows, in PowerShell or cmd: a virtual environment in your project folder
python -m venv .venv
.venv\Scripts\python -m pip install huey capskip requests

Langkah 2: buat queue dan klien pemecah CAPTCHA

Semua yang dibutuhkan Huey ada di tasks.py. Consumer meng-import file itu untuk menemukan task, dan setiap skrip yang memasukkan pekerjaan ke queue juga meng-import-nya.

# tasks.py
import os
from pathlib import Path

from capskip import CapSkip
from huey import SqliteHuey

# The whole queue is one SQLite file. Keep it next to this module, so the
# consumer and every script that imports tasks use the same file, whatever
# folder they are started from.
huey = SqliteHuey(
    "captcha",
    filename=str(Path(__file__).with_name("huey.db")),
    store_intermediate_errors=False,  # get() waits for the last retry
)

# Local mode: CapSkip on this PC. Server mode: set CAPSKIP_HOST (and
# CAPSKIP_API_KEY if key validation is on) to reach it on another machine.
solver = CapSkip(
    apiKey=os.environ.get("CAPSKIP_API_KEY", "capskip"),
    host=os.environ.get("CAPSKIP_HOST", "127.0.0.1"),
    port=int(os.environ.get("CAPSKIP_PORT", "8080")),
)

Tentukan file database dengan path lengkap, seperti di atas. Nama file default-nya adalah huey.db di folder mana pun tempat proses dijalankan. Skrip yang dijalankan dari folder lain lalu membuat huey.db kosong miliknya sendiri, memasukkan task-nya ke sana, dan menunggu hasil yang tidak pernah datang. Mengunci lokasi file di samping tasks.py memberi setiap proses queue yang sama. Selama consumer berjalan, dua file pembantu, huey.db-wal dan huey.db-shm, berada di sampingnya. Keduanya milik write-ahead log SQLite, normal, dan bisa tetap ada setelah penghentian paksa.

SQLite menangani beban itu tanpa error. Dua belas worker dan tiga skrip yang bersama-sama memasukkan 600 task ke queue tidak mendapat error yang menyatakan database terkunci. Di dalam setiap proses, Huey berbagi satu koneksi di balik sebuah lock, dan antar-proses SQLite menunggu hingga 5 detik untuk mendapatkan file itu. Ada satu hal yang perlu diketahui tentang file ini: argumen dan hasil task di-pickle ke dalamnya sebagai byte biasa. Kata sandi yang diteruskan sebagai argumen bisa dibaca di tabel, jadi simpan rahasia di variabel lingkungan atau di tasks.py, bukan di argumen task.

Langkah 3: tulis task CAPTCHA Huey, dan pilih apa yang dicoba ulang

Setiap exception yang dimunculkan task Huey menghabiskan satu percobaan ulang. Itu tepat untuk sebagian kegagalan CapSkip dan sia-sia untuk yang lain, jadi task ini memilahnya.

from capskip import ApiException, ValidationException
from huey import CancelExecution


# Any exception uses one of the two retries, 15 s apart: NetworkException
# when CapSkip is not running, TimeoutException, an unsolvable task.
@huey.task(retries=2, retry_delay=15)
def solve_recaptcha(sitekey, page_url):
    try:
        return solver.recaptcha(sitekey=sitekey, url=page_url)["code"]
    except (ApiException, ValidationException) as exc:
        if "ERROR_CAPTCHA_UNSOLVABLE" in str(exc):
            raise  # this attempt failed; a fresh one may not
        # ERROR_GOOGLEKEY, ERROR_PAGEURL, ERROR_BAD_PARAMETERS and
        # ERROR_KEY_DOES_NOT_EXIST fail the same way on every attempt.
        # CancelExecution's first argument is retry: False ends the task now.
        raise CancelExecution(False, f"{type(exc).__name__}: {exc}") from exc

Tiga kegagalan layak mendapat percobaan berikutnya: NetworkException saat CapSkip belum berjalan, TimeoutException, dan ERROR_CAPTCHA_UNSOLVABLE, yaitu cara CapSkip melaporkan pemecahan yang kali ini tidak berhasil. Consumer mencatat error itu beserta traceback-nya, lalu satu baris yang menyatakan bahwa task dimasukkan ulang ke queue beserta jumlah percobaan ulang yang tersisa. Dengan retry_delay 15 detik, percobaan berikutnya dimulai 16.1 detik setelah kegagalan dalam pengujian kami.

Sitekey yang salah format, URL halaman tanpa http atau https, atau API key yang salah (saat validasi key aktif) ditolak sebelum pemecahan apa pun dimulai, dengan ERROR_GOOGLEKEY, ERROR_PAGEURL, atau ERROR_KEY_DOES_NOT_EXIST. Sitekey atau URL halaman yang kosong mendapat ERROR_BAD_PARAMETERS. Kegagalan ini selalu terjadi dengan cara yang sama, jadi mencoba ulang hanya membuang waktu. CancelExecution milik Huey mengakhiri task tanpa percobaan ulang hanya jika retry bernilai False. Jika dimunculkan begitu saja tanpa argumen, CancelExecution tetap mencoba ulang selama task masih memiliki sisa percobaan ulang. Baca juga signature-nya: argumen posisional pertamanya adalah retry, bukan pesan. Jika ditulis sebagai CancelExecution dengan pesan saja, pesan itu menjadi nilai retry dan dihitung sebagai true. Log lalu menyatakan bahwa task akan dicoba ulang, dan task berjalan lagi dan lagi sampai Anda menghentikan consumer. Memberikan pesan bersama retry=False memunculkan TypeError, karena retry akan mendapat dua nilai. Berikan False lebih dulu, seperti yang dilakukan kode. Consumer lalu mencatat WARNING bahwa task memunculkan CancelExecution dan tidak akan dicoba ulang.

Ada satu batasan dari pemilahan ini: sitekey yang ditolak Google sendiri tetap sampai ke Anda sebagai ERROR_CAPTCHA_UNSOLVABLE, karena CapSkip melaporkan setiap pemecahan yang gagal dengan cara itu. Kasus itu menghabiskan tiga percobaan sebelum gagal. Jika sebuah halaman selalu gagal, periksa sitekey-nya lebih dulu.

Langkah 4: jalankan consumer di Windows

Jalankan consumer dari folder yang berisi tasks.py. Anda tidak perlu mengaktifkan virtual environment jika memanggil exe melalui path-nya.

# In the folder that holds tasks.py, in PowerShell or cmd
.venv\Scripts\huey_consumer tasks.huey -w 4

Panduan lama, dan petunjuk penggunaan milik consumer sendiri, menyebut huey_consumer.py. Huey 3 hanya menginstal huey_consumer.exe, sehingga nama itu gagal di PowerShell dan di cmd dengan pesan bahwa nama itu tidak dikenali. Perintah di atas berfungsi di keduanya, begitu pula .venv\Scripts\python -m huey.bin.huey_consumer tasks.huey. Jika dijalankan dari folder lain, consumer berhenti dengan Error importing tasks.huey dan ModuleNotFoundError: No module named tasks, karena consumer hanya menambahkan folder saat ini ke search path-nya.

Worker thread adalah satu-satunya pilihan nyata di Windows. Dengan -k process, consumer langsung keluar dengan error yang menyatakan huey cannot be run in process-mode on Windows, karena worker proses membutuhkan fork(), yang tidak dimiliki Windows. Worker greenlet membutuhkan gevent yang terinstal. Bagaimanapun, thread memang cocok untuk pekerjaan ini, karena worker menghabiskan hampir seluruh waktu pemecahan untuk menunggu CapSkip.

Setiap worker mengirim permintaannya sendiri, jadi jumlah worker juga merupakan jumlah pemecahan yang diterima CapSkip sekaligus. Dengan 12 worker dan 12 task di queue, ke-12 permintaan itu sampai ke CapSkip dalam 30 milidetik. Bagian reCAPTCHA di CapSkip menjalankan 10 pemecahan sekaligus secara default, sesuai pengaturan Max. Threads, dan mengantrekan sisanya. Empat worker cukup untuk beberapa login. Naikkan -w mendekati batas itu saat queue-nya panjang.

Langkah 5: masukkan pemecahan ke queue dan baca hasilnya sekali

Memanggil task tidak menjalankannya. Pemanggilan itu menulis task ke queue dan mengembalikan handle Result yang bisa Anda tunggu.

# enqueue.py, next to tasks.py: .venv\Scripts\python enqueue.py
from huey.exceptions import ResultTimeout, TaskException

from tasks import huey, solve_recaptcha

result = solve_recaptcha("YOUR_SITEKEY", "https://example.com/login")
try:
    # Three attempts of up to about 5.5 minutes each, plus two 15 s delays.
    token = result.get(blocking=True, timeout=1100)
except TaskException as exc:
    print("solve failed:", exc)
except ResultTimeout:
    print("no result yet: is the consumer running?")
else:
    print("token:", token[:30], "...")
    # Reading the result deleted it from huey.db. This handle keeps its
    # copy, but a new handle for the same task id finds nothing.
    print("read again:", huey.result(result.id))  # None

Penantian 1100 detik mencakup kasus terburuk: tiga percobaan yang masing-masing berjalan sampai batas SDK, ditambah dua jeda percobaan ulang. Task yang gagal memunculkan TaskException, yang pesannya adalah error terakhir dan metadata-nya berisi sisa percobaan ulang serta traceback. Jika tidak ada yang menjawab tepat waktu, Anda mendapat ResultTimeout, yang biasanya berarti consumer tidak berjalan atau memakai file database lain.

Baris store_intermediate_errors di Langkah 2 penting di sini. Dengan default Huey, setiap percobaan yang gagal disimpan sebagai hasil. Dalam pengujian kami, get() memunculkan TaskException setelah kegagalan pertama sementara Huey menjalankan percobaan ulang. Hasil percobaan ulang itu baru terlihat setelah reset() dipanggil pada handle. Jika opsi itu dimatikan, get() menunggu percobaan terakhir.

Hasil hanya bisa dibaca sekali. Membacanya akan menghapusnya dari file, seperti yang dilakukan CapSkip dengan jawabannya sendiri. Handle yang membacanya tetap menyimpan salinannya, tetapi huey.result() dengan id task yang sama mengembalikan None sesudahnya. Berikan preserve=True ke get() jika dua bagian kode Anda membutuhkan nilai itu. Task yang mengembalikan None sama sekali tidak menyimpan apa pun, sehingga menunggunya berakhir dengan ResultTimeout.

Mengapa pemecahan yang macet membutuhkan timeout sendiri

Huey 3 menerima opsi timeout pada task, tetapi pada worker thread opsi itu tidak berpengaruh apa pun. Thread tidak bisa diinterupsi dari luar, jadi Huey hanya memeriksanya jika task itu sendiri memanggil task.check_timeout(). Task dengan timeout=2 yang menjalankan sleep selama lima detik selesai secara normal. Worker proses, tempat timeout bisa ditegakkan, ditolak di Windows.

Itu penting karena SDK CapSkip tidak menyetel timeout HTTP pada permintaannya. Jika CapSkip menerima koneksi tetapi tidak pernah menjawab, pemanggilan itu menunggu selamanya. Dalam pengujian kami, dua worker tertahan dalam keadaan itu tanpa satu baris log pun, dan task di queue di belakangnya tidak pernah dimulai. Kedua worker itu masih macet 45 detik setelah pemecah CAPTCHA pulih. Perbaikannya adalah memberi pemanggilan HTTP milik SDK sebuah timeout. Taruh kode ini di tasks.py, di level modul, agar berjalan sebelum pemecahan apa pun.

import functools
import types

import requests
import capskip.api

# capskip 1.3.0 calls requests.post/get with no timeout, and Huey cannot stop
# a thread worker that is stuck in one. Give every SDK call 5 s to connect
# and 30 s to answer. Module level in tasks.py, so it runs before any solve.
capskip.api.requests = types.SimpleNamespace(
    RequestException=requests.RequestException,
    post=functools.partial(requests.post, timeout=(5, 30)),
    get=functools.partial(requests.get, timeout=(5, 30)),
)

Dengan kode itu, pengiriman tugas yang macet memunculkan NetworkException setelah 30.0 detik, dan task dicoba ulang. Pemeriksaan status yang macet berlangsung lebih lama, karena SDK menganggap polling yang gagal sebagai belum siap dan terus melakukan polling sampai recaptchaTimeout miliknya sendiri, yaitu 300 detik. Percobaan itu berakhir dengan TimeoutException setelah sekitar 333 detik, dan percobaan ulangnya berhasil memecahkan CAPTCHA. Dalam kedua kasus, worker kembali bebas. Perbaikan ini mengganti referensi requests di dalam capskip.api, bagian internal SDK, jadi periksa lagi saat Anda meng-upgrade capskip.

Pemecahan terjadwal yang tidak bisa saling tumpang tindih

Task periodik bisa mengulang pemecahan dengan timer, misalnya untuk menjaga login tetap segar. Contoh lengkap di bawah melakukan login yang sebenarnya. Task periodik tidak menerima argumen, jadi sitekey dan URL berada di dalam fungsi.

from huey import crontab


# Every 15 minutes. The lock goes under periodic_task: when a run is due
# while the previous one is still solving, another worker skips it instead
# of starting a second solve for the same login.
@huey.periodic_task(crontab(minute="*/15"))
@huey.lock_task("login")
def refresh_login():
    result = solver.recaptcha(sitekey="YOUR_SITEKEY", url="https://example.com/login")
    print("new token:", result["code"][:30], "...")

Consumer memeriksa task periodiknya sekali saat mulai, lalu setiap 60 detik dihitung dari saat mulai itu. Jadi eksekusi yang jatuh tempo pada menit berjalan langsung dimulai. Jika sebuah pemecahan memakan waktu lebih lama dari interval, Huey tetap memasukkan eksekusi berikutnya ke queue. Dengan beberapa worker, worker yang sedang bebas akan memulainya selagi eksekusi pertama masih memecahkan CAPTCHA. Lock mencegah hal itu: eksekusi baru mencatat WARNING bahwa eksekusi itu tidak dijalankan karena tidak bisa memperoleh lock, lalu dilewati. Dengan satu worker, tidak ada yang tumpang tindih, tetapi eksekusi yang terlambat menumpuk di queue lalu dijalankan satu per satu secara berurutan. Tambahkan argumen expires dalam detik, misalnya expires=600, ke decorator periodic_task untuk membuang eksekusi yang menunggu terlalu lama.

Lock disimpan di file database, sehingga tetap ada setelah crash. Setelah penghentian paksa, lock yang tertinggal membuat setiap eksekusi berikutnya dilewati. Jalankan consumer dengan -f untuk menghapus lock decorator, dan consumer akan mencatat bahwa ia menemukan lock usang. Huey 3.4 juga menambahkan opsi ttl ke lock_task, tetapi SqliteHuey tidak mendukungnya dan memunculkan NotImplementedError saat lock diambil.

File task CAPTCHA Huey lengkap

Versi ini mengambil halaman login, membaca sitekey dan token CSRF, memecahkan CAPTCHA tepat sebelum form dikirim, lalu mengirim form dengan header Referer. Versi ini menyediakan login sesuai permintaan sebagai log_in dan secara terjadwal sebagai scheduled_login. Keduanya berbagi satu lock, sehingga keduanya tidak pernah memecahkan CAPTCHA untuk akun yang sama secara bersamaan. Ganti URL dan kredensialnya, lalu jalankan consumer dengan -f.

# tasks.py: pip install huey capskip requests
# Start: .venv\Scripts\huey_consumer tasks.huey -w 4 -f
import functools
import logging
import os
import re
import types
from pathlib import Path

import requests
import capskip.api
from capskip import ApiException, CapSkip, ValidationException
from huey import CancelExecution, SqliteHuey, crontab

LOGIN_URL = "https://example.com/login"
USERNAME, PASSWORD = "YOUR_USERNAME", "YOUR_PASSWORD"

huey = SqliteHuey(
    "captcha",
    filename=str(Path(__file__).with_name("huey.db")),  # same file from any folder
    store_intermediate_errors=False,  # get() waits for the last retry
)
log = logging.getLogger("huey.captcha")  # printed by the consumer

# The SDK's HTTP calls have no timeout; give them one so a stuck CapSkip
# cannot hold a worker thread forever.
capskip.api.requests = types.SimpleNamespace(
    RequestException=requests.RequestException,
    post=functools.partial(requests.post, timeout=(5, 30)),
    get=functools.partial(requests.get, timeout=(5, 30)),
)
solver = CapSkip(
    apiKey=os.environ.get("CAPSKIP_API_KEY", "capskip"),
    host=os.environ.get("CAPSKIP_HOST", "127.0.0.1"),
    port=int(os.environ.get("CAPSKIP_PORT", "8080")),
)


def solve(sitekey, page_url):
    try:
        return solver.recaptcha(sitekey=sitekey, url=page_url)["code"]
    except (ApiException, ValidationException) as exc:
        if "ERROR_CAPTCHA_UNSOLVABLE" in str(exc):
            raise  # worth another attempt
        # A refused sitekey, page URL or API key fails the same way every time.
        log.error("not retrying: %s: %s", type(exc).__name__, exc)
        raise CancelExecution(False, f"{type(exc).__name__}: {exc}") from exc


def field(html, pattern):
    match = re.search(pattern, html)
    if not match:
        raise ValueError(f"not found on the login page: {pattern}")
    return match.group(1)


def login():
    with requests.Session() as session:
        page = session.get(LOGIN_URL, timeout=30)
        sitekey = field(page.text, r'data-sitekey="([^"]+)"')
        csrf = field(page.text, r'name="csrfmiddlewaretoken" value="([^"]+)"')
        token = solve(sitekey, LOGIN_URL)  # solve right before the post
        reply = session.post(LOGIN_URL, timeout=30, headers={"Referer": LOGIN_URL}, data={
            "csrfmiddlewaretoken": csrf,
            "username": USERNAME,
            "password": PASSWORD,
            "g-recaptcha-response": token,
        })
        reply.raise_for_status()  # a refused login fails the attempt
        log.info("logged in (HTTP %s)", reply.status_code)
        return reply.status_code


# Both tasks take the same lock, so an on-demand login never runs while a
# scheduled one is solving, and the other way round.

# On demand: from tasks import log_in; log_in().get(blocking=True, timeout=1100)
@huey.task(retries=2, retry_delay=15)  # a locked attempt uses a retry
@huey.lock_task("login")
def log_in():
    return login()


# On a schedule; a run that comes due while the lock is held is skipped.
@huey.periodic_task(crontab(minute="*/15"))
@huey.lock_task("login")
def scheduled_login():
    login()

Pemecahan terjadi di dalam percobaan yang sama dengan pengiriman form, sehingga percobaan ulang selalu mengambil halaman baru dan memecahkan lagi. Token tidak pernah dibawa dari percobaan yang gagal, dan itu penting karena Google hanya membiarkan token reCAPTCHA hidup selama dua menit. Login yang ditolak dan mengembalikan error HTTP, seperti 403, menggagalkan percobaan itu lewat raise_for_status() lalu dicoba ulang dua kali, masing-masing dengan halaman baru dan pemecahan baru. CapSkip tidak mengenakan biaya per pemecahan, jadi hal itu hanya memakan waktu. Banyak situs menjawab kata sandi yang salah dengan status 200 dan form yang sama lagi, jadi tambahkan pemeriksaan untuk situs Anda, misalnya URL setelah pengiriman form. Jika log_in sesuai permintaan mendapati eksekusi terjadwal sedang memegang lock, log_in dilewati dengan WARNING yang sama, dan percobaan itu menghabiskan satu percobaan ulang. Dua percobaan ulang berjarak 15 detik memberinya total sekitar 30 detik waktu tunggu. Jika pemecahan terjadwal memakan waktu lebih lama, ketiga percobaan dilewati dan get() memunculkan TaskException, dengan TaskLockedException di pesannya. Naikkan retry_delay pada log_in jika pemecahan Anda biasanya memakan waktu lebih lama dari itu.

Untuk login sesuai permintaan dari skrip lain, import log_in dari tasks, panggil, lalu tunggu hasilnya dengan get(blocking=True, timeout=1100), seperti di Langkah 5. Nilai kembaliannya adalah status HTTP akhir setelah pengiriman form. Baris log dari task muncul di jendela consumer di samping baris log milik Huey sendiri.

Menghentikan consumer dengan bersih

Tekan Ctrl+C sekali di jendela consumer. Huey berhenti mengambil task baru, menunggu task yang sedang berjalan, lalu keluar. Dalam pengujian kami, consumer yang dihentikan di tengah pemecahan keluar 18 detik kemudian, begitu pemecahan itu selesai. Consumer yang menganggur keluar dalam waktu kurang dari sepersepuluh detik. Ctrl+C kedua berperilaku berbeda tergantung versinya: Python 3.14 langsung keluar, sedangkan 3.13 tetap menunggu task yang sedang berjalan, sehingga pemecahan yang macet tanpa timeout di atas hanya bisa dimatikan paksa.

Cara apa pun yang lebih cepat daripada penghentian graceful akan menghilangkan task yang sedang berjalan. Termasuk di dalamnya Ctrl+C kedua di 3.14, Ctrl+Break, dan opsi -t, yang membatasi lama penantian graceful: dengan -t 5, consumer keluar sekitar 5.1 detik setelah Ctrl+C. Task yang hilang itu sudah keluar dari queue, sehingga tidak berjalan lagi, dan lock-nya tetap tertinggal. Itulah sebabnya consumer pada contoh lengkap dijalankan dengan -f.

Menjalankan CapSkip di mesin lain

Consumer dan pemecah CAPTCHA tidak harus berada di PC yang sama. Alihkan CapSkip ke mode Server di pengaturan koneksi, dan CapSkip akan mendengarkan di alamat jaringan atau IP publik Anda. File tasks.py Anda sudah membaca alamat itu dari variabel lingkungan, jadi setel variabelnya sebelum Anda menjalankan consumer.

# PowerShell, before starting the consumer: CapSkip runs in Server mode
# on another Windows machine on your network
$env:CAPSKIP_HOST = "192.168.1.50"
$env:CAPSKIP_API_KEY = "YOUR_API_KEY"
# $env:CAPSKIP_PORT = "8080"   only if you changed the port
.venv\Scripts\huey_consumer tasks.huey -w 4 -f

Gunakan IP publik statis jika rutenya melewati internet, dan aktifkan validasi API key, dengan key yang sama di CAPSKIP_API_KEY. CapSkip membuka port-nya untuk semua alamat saat mode Server dimulai, jadi untuk membatasinya hanya pada mesin yang Anda harapkan, tambahkan aturan blokir Windows Firewall untuk alamat lainnya. Consumer lalu bisa berjalan di mesin mana pun yang menjangkau port itu, dan pemecah CAPTCHA tetap berupa mesin Windows milik Anda sendiri dengan pemecahan tanpa kuota.

Kesalahan umum CAPTCHA Huey

Apa yang Anda lihatPenyebabPerbaiki
huey_consumer.py tidak dikenaliHuey 3 hanya menginstal huey_consumer.exeJalankan .venv\Scripts\huey_consumer
huey cannot be run in process-mode on WindowsWorker proses membutuhkan fork()Gunakan worker thread default
ModuleNotFoundError: No module named tasksConsumer dijalankan di luar folder yang berisi tasks.pyJalankan dari folder itu
ResultTimeout padahal consumer sedang berjalanSkrip dan consumer memakai file huey.db yang berbedaBeri SqliteHuey path lengkap ke file itu
get() melaporkan kegagalan, lalu task berhasilstore_intermediate_errors aktif, sehingga setiap percobaan yang gagal disimpanSetel store_intermediate_errors=False
Task yang seharusnya berhenti terus mencoba ulangCancelExecution menerima pesan sebagai argumen retry-nyaMunculkan CancelExecution(False, message)
Worker berhenti mengambil task dan tidak mencatat apa punSebuah pemecahan macet di pemanggilan HTTP tanpa timeoutBeri timeout pada permintaan HTTP milik SDK
Setiap eksekusi terjadwal dilewatiLock usang dari consumer yang dimatikan paksaJalankan ulang consumer dengan -f

FAQ

Bisakah saya memakai RedisHuey sebagai pengganti SqliteHuey?

Bisa. Task, percobaan ulang, dan lock di panduan ini bekerja dengan cara yang sama. Instal juga paket redis, lalu buat queue dengan RedisHuey sebagai pengganti SqliteHuey. Namun RedisHuey membutuhkan server Redis, dan Windows tidak menyertakannya. Di PC yang sudah menjalankan CapSkip, file SQLite membuat Anda tidak perlu menjalankan layanan kedua. Untuk queue yang tersebar di banyak mesin, Redis lebih cocok, seperti di panduan memecahkan CAPTCHA di task Celery.

Mengapa task pertama setelah periode menganggur dimulai terlambat?

Consumer yang menganggur memeriksa database makin lama makin jarang, hingga setiap 10 detik secara default. Dengan empat worker, task pertama setelah periode menganggur menunggu 3 hingga 7 detik dalam pengujian kami. Jalankan consumer dengan -m 1 untuk membatasi penantian itu pada satu detik; setelah itu penantiannya tetap di bawah satu detik.

Apakah ini berfungsi di proyek Django?

Ya, melalui huey.contrib.djhuey. Setel huey_class ke huey.SqliteHuey beserta filename di pengaturan HUEY, lalu jalankan consumer dengan manage.py run_huey. Ada satu default yang mengejutkan banyak orang: saat DEBUG aktif, djhuey menjalankan task secara langsung di dalam request, sehingga pemecahan memblokir halaman sampai CapSkip menjawab. Setel immediate ke False di pengaturan HUEY untuk menguji queue yang sebenarnya.

Bisakah consumer berjalan di mesin yang berbeda dari CapSkip?

Bisa. Alihkan CapSkip ke mode Server di pengaturan koneksi, agar ia mendengarkan di alamat jaringan, bukan di loopback, lalu setel CAPSKIP_HOST ke alamat itu sebelum consumer dijalankan. Task lalu memanggilnya melalui API HTTP yang sama dari mesin mana pun yang bisa menjangkau port tersebut. Tambahkan aturan blokir Windows Firewall untuk alamat yang seharusnya tidak bisa menjangkaunya. Pemecah CAPTCHA tetap berjalan di perangkat milik Anda, dan tidak ada pemecahan yang melewati layanan pihak ketiga.

Versi singkatnya

Untuk task CAPTCHA Huey di Windows, letakkan file SqliteHuey di samping tasks.py, matikan store_intermediate_errors, dan coba ulang hanya kegagalan CapSkip yang bisa diatasi dengan percobaan baru, lalu akhiri sisanya dengan CancelExecution(False, message). Jalankan .venv\Scripts\huey_consumer dengan worker thread dari folder yang berisi tasks.py, beri pemanggilan HTTP milik SDK sebuah timeout, ingat bahwa setiap hasil hanya bisa dibaca sekali, dan pasang lock pada pemecahan terjadwal. Dokumentasi consumer Huey mencantumkan setiap opsi consumer yang dipakai di sini.

Queue dalam satu file dan pemecah CAPTCHA di PC yang sama menjaga seluruh pekerjaan tetap berada di perangkat yang Anda kendalikan. Itulah inti dari solusi lokal untuk bypass captcha: setiap percobaan ulang gratis, sehingga task bisa leluasa mencoba lagi.