
Nikolai Smirnov
Software Development Lead
Diterbitkan Oct 29, 2026
Diperbarui Oct 29, 2026 · min baca

Dua agen browser menemukan CAPTCHA yang didukung selama dua task terpisah dan terotorisasi. Agen A mulai lebih dulu, tetapi Agen B menerima hasil lebih dulu. Jika aplikasi hanya memberikan hasil berikutnya ke tab pertama yang sedang menunggu, kedua job bisa terdampak meskipun tiap permintaan solver itu valid.
Ini adalah masalah korelasi task. Lebih banyak percobaan ulang tidak akan memperbaiki hasil yang dikirim ke halaman yang salah. Aplikasi perlu mengingat item kerja browser mana yang membuat setiap task solver dan apakah item kerja itu masih relevan ketika respons tiba.
CapSolver mengembalikan pengenal task untuk pekerjaan API asinkron. Panduan ini menjelaskan cara mempertahankan asosiasi tersebut di antara agen-agen paralel, dengan contoh lokal kecil yang dapat Anda jalankan sebelum menghubungkan solver nyata. Panduan ini tidak mengklaim tolok ukur konkurensi atau keberhasilan CAPTCHA produksi.
Agen browser harus menyimpan job aplikasi, pemilik halaman, dan ID task solver yang dikaitkan dengan satu percobaan.
API createTask mengembalikan taskId untuk task asinkron. Simpan saat respons pembuatan itu diterima. API getTaskResult menggunakan pengenal tersebut untuk mengambil hasil yang sesuai.
Aplikasi Anda juga memerlukan pengenal item kerja miliknya sendiri dan referensi ke pemilik browser. Ini adalah field milik aplikasi, bukan parameter tambahan permintaan CapSolver. Label halaman seperti page-a dalam contoh mengidentifikasi worker yang memiliki halaman; itu bukan handle browser yang dapat digunakan ulang atau kredensial API.
Tambahkan versi percobaan kecil, disebut epoch di bawah ini. Tingkatkan nilainya ketika navigasi baru atau percobaan challenge baru membuat hasil yang masih tertunda menjadi tidak tepat lagi. URL saja tidak cukup: dua job dapat mengunjungi URL yang sama, dan satu halaman dapat memuat state berbeda tanpa mengganti alamatnya.
Dokumentasi browser-context Playwright menjelaskan isolasi state browser. Isolasi konteks dan korelasi task menyelesaikan masalah yang berbeda. Cookie yang terpisah tidak otomatis merutekan hasil solver ke worker yang tepat.
Urutan penyelesaian menggambarkan kapan hasil tiba, bukan job browser mana yang memilikinya.
Dokumentasi asyncio.as_completed Python menjelaskan pemrosesan awaitable saat mereka selesai. Jika orkestrasi Anda menggunakan callback berdasarkan urutan penyelesaian, setiap hasil harus membawa asosiasinya sendiri alih-alih bergantung pada posisi dalam daftar halaman yang menunggu.
Perlakukan pembuatan task dan pengikatannya sebagai satu serah-terima lokal: validasi respons pembuatan, simpan ID yang dikembalikan dengan item kerja, lalu izinkan pengambilan hasil. Implementasi berbasis callback membutuhkan rencana setara untuk hasil yang tiba sebelum pengikatan lokalnya terlihat. Jangan abaikan race condition itu sebagai “halaman tidak dikenal” dan langsung membuat task berbayar baru.
Antarmuka antrean Python dapat membantu meneruskan satu item kerja lengkap di antara worker lokal. Antrean bukan pengganti pemetaan: bawa pengenal tersebut bersama hasil hingga sampai ke pemilik halaman.
Terima hasil untuk dikirim hanya ketika ID task dikenali dan percobaan yang tercatat masih milik halaman aktif.
Gunakan satu pemilik untuk memperbarui state ini dalam aplikasi kecil. Dalam layanan terdistribusi, gunakan penyimpanan yang andal dan klaim atomik atau kontrol konkurensi setara. Dictionary Python yang dibagikan secara informal antar proses tidak dapat memberikan jaminan tersebut.
Contoh di bawah ini adalah fixture perutean lokal, bukan metode SDK resmi atau integrasi solver lengkap. Ia menggunakan ID task hasil rekayasa dan fixture_marker, yang bukan token CAPTCHA atau field solusi CapSolver. Jalankan dengan Python 3; tidak memerlukan paket pihak ketiga, kunci API, browser, atau permintaan jaringan.
def accept_result(reply, pending, current_epochs):
task_id = reply.get('taskId')
if not isinstance(task_id, str) or type(reply.get('errorId')) is not int:
return 'malformed_reply', None
job = pending.get(task_id)
if job is None:
return 'unknown_or_duplicate', None
if current_epochs.get(job['page_id']) != job['epoch']:
pending.pop(task_id)
return 'stale_page', None
if reply.get('errorId', 0) != 0:
pending.pop(task_id)
return 'solver_error', None
if reply.get('status') != 'ready':
return 'pending', None
if not reply.get('solution'):
pending.pop(task_id)
return 'missing_solution', None
pending.pop(task_id)
return 'ready_for_owner', (job['page_id'], reply['solution'])
pending = {
'fixture-task-a': {'page_id': 'page-a', 'epoch': 1},
'fixture-task-b': {'page_id': 'page-b', 'epoch': 1},
}
epochs = {'page-a': 1, 'page-b': 1}
for task_id in ['fixture-task-b', 'fixture-task-a']:
reply = {'taskId': task_id, 'errorId': 0, 'status': 'ready',
'solution': {'fixture_marker': task_id}}
state, target = accept_result(reply, pending, epochs)
print(task_id, state, target[0] if target else None)
Contoh ini mencetak dua baris berikut:
fixture-task-b ready_for_owner page-b
fixture-task-a ready_for_owner page-a
Task B selesai lebih dulu dan tetap kembali ke halaman B. Fungsi ini dengan sengaja menyerahkan hasil ke pemiliknya tanpa mengisi atau mengirim halaman. Gantilah fixture hanya setelah Anda memiliki parser hasil spesifik-task yang terdokumentasi dan operasi browser yang didukung.
Untuk worker polling, simpan ID task yang digunakan dalam permintaan sebagai bagian dari item kerja lokal. Jika respons menyertakan ID task, verifikasi bahwa nilainya cocok; jangan gunakan ID respons yang tidak tepercaya atau tidak cocok untuk melabeli ulang permintaan. Fixture mengasumsikan bahwa asosiasi ini sudah divalidasi sebelum accept_result dipanggil.
Tukarkan Kode Bonus CapSolver Anda
Tingkatkan anggaran otomatisasi Anda seketika!
Gunakan kode bonus CAP26 saat mengisi saldo akun CapSolver Anda untuk mendapatkan bonus 5% tambahan pada setiap pengisian — tanpa batas.
Tukarkan sekarang di Dashboard CapSolver
Hasil yang terlambat atau berulang harus menghasilkan state eksplisit alih-alih diterapkan ke tab mana pun yang sedang aktif.
Tandai percobaan lama sebagai kedaluwarsa (stale) ketika halamannya ditutup, dinavigasi, atau memulai challenge pengganti. Fixture membandingkan epoch yang tersimpan dengan current_epochs; menghapus halaman yang ditutup juga menggagalkan pengecekan itu. Jangan memindahkan hasil lama ke percobaan baru hanya karena hostname-nya cocok.
Pemilik halaman Anda harus memeriksa percobaan sekali lagi tepat sebelum menggunakan hasil yang dikirim. Pengecekan milik fixture dan aksi browser berikutnya adalah operasi terpisah. Menjaga navigasi halaman dan penerapan hasil di bawah pemilik yang sama mencegah worker lain mengubah halaman di antara keduanya.
Pertahankan pengikatan task yang ada sementara solver melaporkan state non-terminal. Ikuti panduan polling dokumentasi task saat ini dan tenggat job Anda. Membuat task pengganti setiap kali hasil belum siap dapat melipatgandakan pekerjaan tertunda tanpa menyelesaikan permintaan asli.
Catat kegagalan pada item kerja yang bersesuaian. Fixture memisahkan error solver, amplop (envelope) yang rusak, dan solusi yang hilang. Parser produksi juga harus memvalidasi field solusi secara tepat untuk tipe task yang dipilih; dictionary yang tidak kosong tidak cukup untuk membuktikan token yang dapat digunakan.
Klaim pengiriman satu kali saja. Fixture lokal menghapus binding yang sudah ready, sehingga pengulangan diklasifikasikan sebagai tidak dikenal atau duplikat. Worker produksi memerlukan catatan terminal yang andal dan kebijakan acknowledgement jika pengiriman atau eksekusi browser dapat gagal. Jangan gunakan contoh in-memory ini sebagai antrean terdistribusi dengan jaminan exactly-once.
Verifikasikan kepemilikan dan perilaku penolakan yang benar sebelum menarik kesimpulan tentang throughput.
Pemeriksaan lokal mencakup urutan penyelesaian terbalik, task yang sedang berlangsung, ID tak dikenal, percobaan yang berubah, halaman tertutup, respons error, solusi kosong, amplop rusak, dan pengiriman duplikat. Pemeriksaan ini lolos untuk fungsi yang dipublikasikan. Mereka tidak menguji pemecahan CAPTCHA nyata, pengisian balik browser, atau penerimaan aplikasi.
Untuk pengujian end-to-end yang terotorisasi, tambahkan pemanggilan pembuatan dan pengambilan task nyata, simpan hasil sensitif di worker browser, dan konfirmasikan hasil aplikasi yang dimaksud setelah langkah solve yang didokumentasikan. Jika halaman masih menampilkan challenge atau record yang diharapkan tidak ada, catat hasil itu secara terpisah dari kesiapan solver.
Buat log tetap berguna tanpa menyalin token mentah, cookie, atau kunci API. Simpan ID item kerja, ID task, nama tahap, dan informasi error yang disanitasi. Panduan timeout API yang sudah ada membahas perilaku penungguan; perhatian artikel ini adalah job mana yang menerima hasil akhirnya. Glosarium concurrency memberikan latar belakang tentang pekerjaan simultan tanpa menyiratkan janji kinerja.
Pastikan setiap solve yang didukung tetap terikat pada item kerja yang memintanya. CapSolver menyediakan hasil solver; aplikasi Anda yang merutekan hasil tersebut, memeriksa apakah percobaannya masih berlaku, dan memverifikasi task browser. Pemisahan ini membuat agen paralel tetap independen ketika hasil tiba tidak berurutan.
T: Bisakah dua agen browser berbagi satu variabel task yang tertunda?
Satu variabel mutable tidak aman jika pekerjaan berikutnya menimpa asosiasi yang lebih awal. Simpan binding terpisah untuk setiap task solver aktif dan pemilik halamannya.
T: Apakah URL halaman cukup untuk mengidentifikasi tujuan?
Tidak. Tab yang berbeda dapat berbagi URL, dan sebuah halaman dapat mengubah state di alamat yang sama. Simpan identitas item kerja dan versi percobaan yang masih berlaku.
T: Bisakah saya menggunakan ulang hasil ready setelah halaman bernavigasi?
Jangan berasumsi bahwa hasil itu masih berlaku. Perlakukan percobaan lama sebagai kedaluwarsa dan inspeksi halaman baru sebelum memutuskan solve selanjutnya yang diizinkan.
T: Apakah contoh ini memecahkan atau mengirim CAPTCHA nyata?
Tidak. Contoh ini menguji perutean lokal dengan pengenal buatan dan hasil inert. Pemecahan berbayar dan penerimaan aplikasi memerlukan uji integrasi terpisah.
T: Apakah contoh dictionary ini aman di antara worker terdistribusi?
Tidak. Contoh ini mengasumsikan satu pemilik dalam satu proses. Eksekusi terdistribusi memerlukan state task yang andal, klaim pengiriman atomik, dan kebijakan penanganan kegagalan.

Nikolai Smirnov
Software Development Lead
Building dependable software for complex automation.
TENTANG PENULIS
Baca hasil alat CAPTCHA dengan benar: bedakan kesalahan transport, tugas yang masih tertunda, keluaran solver, dan keberhasilan browser sebelum membiarkan agen AI melanjutkan.

Pilih API CAPTCHA atau MCP untuk agen AI Anda dengan membandingkan kontrol tugas, penemuan alat, penanganan hasil, dan tanggung jawab browser sebelum Anda melakukan integrasi.
