
Emma Foster
Machine Learning Engineer

ReCaptchaV2TaskProxyLess, websiteURL, dan websiteKey, lalu mengembalikan gRecaptchaResponse setelah hasil siap.needs_review mencegah loop dan pemberitahuan stok yang menyesatkan.Pengumpulan data inventaris toko terlihat sederhana hingga halaman ritel berubah perilaku berdasarkan lokasi, memerlukan pemilih toko, atau menghentikan sesi browser yang diizinkan di titik pemeriksaan CAPTCHA. Sebuah pengumpul yang andal harus mempertahankan konteks produk dan toko, menyelesaikan checkpoint melalui sesi yang sama, dan membuktikan bahwa halaman mengembalikan keadaan stok yang sebenarnya. CapSolver dapat berfungsi sebagai infrastruktur CAPTCHA di langkah pemulihan yang terkendali.
Panduan ini fokus pada skenario operasi ritel konkret: memantau ketersediaan produk publik untuk perencanaan pemenuhan, QA merchandising, atau pemberitahuan stok yang terlihat oleh pelanggan. Tidak mengasumsikan bahwa tugas CAPTCHA yang berhasil berarti permintaan inventaris berhasil. Alur kerja hanya berakhir ketika aplikasi target menyediakan hasil inventaris yang dikenali dan pengumpul mencatat cukup bukti untuk membedakan "habis stok" dari "tidak diketahui".
Pengumpulan data inventaris toko harus mengembalikan catatan kecil dan stabil yang dapat dipercaya oleh sistem downstream. Catatan yang berguna mencakup penjual, identifikasi produk kanonik, toko atau area pos yang diminta, ketersediaan yang diamati, waktu pengamatan, dan sumber bukti. Harga mungkin termasuk, tetapi tidak boleh menggantikan status stok yang jelas.
{
"retailer": "authorized-demo-store",
"product_id": "SKU-4821",
"store_id": "STORE-017",
"postal_area": "10001",
"availability": "in_stock",
"quantity_hint": "limited",
"observed_at": "2026-08-13T09:15:00Z",
"source": "product-page",
"verification": "inventory-label-and-store-id",
"captcha_recovery": "completed"
}
Inputnya adalah URL produk ditambah konteks toko yang diizinkan. Operasi memilih atau memverifikasi lokasi, mendeteksi titik pemeriksaan verifikasi, menyelesaikannya ketika diizinkan, membaca status inventaris, dan menyederhanakan hasilnya. Outputnya adalah catatan di atas atau status terminal seperti not_found, out_of_stock, needs_review, atau policy_denied. Jangan pernah mengubah timeout, loop tantangan, dinding login, atau respons yang tidak valid menjadi out_of_stock; kesalahan ini menciptakan sinyal bisnis yang salah.
FAQ penyelesaian CAPTCHA CapSolver menjelaskan batas layanan, sementara panduan otomatisasi browser memberikan konteks yang lebih luas untuk mempertahankan status halaman. Dalam kasus pengguna ini, browser memiliki navigasi dan bukti, CapSolver memiliki tugas CAPTCHA yang terdokumentasi, dan aplikasi Anda memiliki otorisasi, kebijakan ulang, dan verifikasi akhir.
Seorang pengumpul ritel biasanya melakukan beberapa tindakan berstatus sebelum inventaris muncul: memuat halaman produk, menerima pengaturan wilayah, memilih toko, membuka panel pengambilan, atau memanggil endpoint inventaris publik yang diinisiasi oleh halaman. CAPTCHA dapat muncul sebelum halaman pertama dirender atau setelah salah satu tindakan tersebut. Jika pengumpul menganggapnya sebagai HTML umum, selektor gagal dan pekerjaan mungkin menulis catatan kosong atau salah.
Jawaban yang benar adalah transisi status, bukan ulang coba buta. Pengumpul berpindah dari collecting ke captcha_required, membekukan konteks produk dan lokasi saat ini, mengumpulkan hanya bidang tantangan yang terdokumentasi, dan memanggil adapter penyedia. Respons penyedia yang siap memindahkan alur kerja ke apply_solution; penerimaan aplikasi memindahkannya ke verify_inventory. Hasil yang ditolak, checkpoint berulang, host yang tidak terduga, atau tenggat waktu habis memindahkannya ke needs_review.
Desain ini menjaga tiga kebenaran yang berbeda terpisah:
Hanya kebenaran ketiga yang memungkinkan pekerjaan untuk menerbitkan catatan inventaris. Pemisahan ini sangat penting ketika ritel menggunakan konten yang disimpan, mengalihkan antar domain regional, atau memperbarui stok secara asinkron setelah HTML awal dimuat.
Gunakan enam komponen dengan tanggung jawab sempit.
Daftar cakupan mencantumkan hostname yang disetujui, tujuan pengumpulan, jalur produk, wilayah toko, jadwal, dan pemilik kontak. Ini juga harus mencatat pengecualian: area akun yang diotentikasi, portal karyawan, checkout, pembayaran, profil pribadi, dan setiap jalur yang berada di luar cakupan menurut pemilik situs atau perjanjian Anda. Permintaan yang tidak sesuai dengan daftar ini berhenti sebelum browser dibuka.
Browser menetapkan lokal, pemilihan toko, cookie, dan status navigasi. Pertahankan satu pemeriksaan produk dalam satu konteks browser. Menggunakan cookie yang tidak terkait antar toko dapat menciptakan drift lokasi yang membingungkan; menghapus konteks selama pemulihan CAPTCHA dapat membatalkan solusi. Hanya pertahankan data minimal yang diperlukan untuk pekerjaan dan hapus sesuai kebijakan penyimpanan Anda.
Detektor mencari elemen widget eksplisit, bidang respons yang diketahui, skrip tantangan, atau rute verifikasi. Ia juga membedakan CAPTCHA dari masalah biasa seperti 404, dialog persetujuan, toko tidak tersedia, atau kesalahan aplikasi. Glosarium CapSolver berguna untuk menjaga konsistensi istilah tantangan dalam log dan buku kerja.
Adapter menerima permintaan sempit yang mencakup jenis tantangan, URL halaman, kunci situs, dan ID korelasi. Ia membaca kunci API dari penyimpanan rahasia, membuat satu tugas, memantau tugas yang sama dengan tenggat waktu, memvalidasi skema hasil, dan mengembalikan keberhasilan atau kegagalan yang dinormalkan. Ia tidak memutuskan situs mana yang diizinkan dan tidak menulis data inventaris.
Ekstraktor memetakan halaman atau respons publik ke skema inventaris yang stabil. Ia sebaiknya memilih identifikasi produk yang tahan lama, ID toko, data terstruktur, dan teks ketersediaan yang jelas daripada posisi visual yang rapuh. Jika halaman mengandung beberapa mode penukaran, catat pengambilan, pengiriman, dan pengiriman lokal secara terpisah daripada menggabungkannya menjadi satu boolean.
Lapisan bukti menyimpan fakta diagnostik yang tidak sensitif: ID korelasi, hostname yang diizinkan, ID produk, ID toko, jenis tantangan, ID tugas penyedia, waktu yang berlalu, status akhir, dan selektor atau bidang respons yang digunakan untuk verifikasi. Ia harus menghapus token, cookie, kunci API, alamat, dan data pelanggan apa pun. Beri pemberitahuan hanya pada perubahan status yang berarti dan butuh dua pengamatan ketika hasil transien tunggal bisa menyebabkan kebisingan operasional.
Sebelum mengimplementasikan pemulihan CAPTCHA, konfirmasikan bahwa Anda memiliki izin untuk mengotomasi halaman ritel yang dipilih dan bahwa tujuan pengumpulan didokumentasikan. Hormati batas kontrak, hukum yang berlaku, instruksi robots di mana berlaku untuk penggunaan Anda, dan laju permintaan yang wajar. Protokol Penolakan Robot menggambarkan petunjuk crawler standar; ini adalah satu sinyal dalam tinjauan otorisasi yang lebih luas, bukan pemberian akses.
Gunakan prasyarat berikut:
requests dan Playwright terinstal.Rahasia harus berasal dari lingkungan yang dikelola atau penyimpanan rahasia. Panduan manajemen rahasia OWASP mendukung pemisahan kredensial dari kode aplikasi, log, dan artefak pembuatan. Jangan tempatkan kunci klien, cookie, token yang diselesaikan, atau alamat pelanggan dalam artikel, prompt, gambar layar, atau tiket pemecahan masalah.
Detektor harus berjalan setelah setiap tindakan yang dapat memicu halaman verifikasi: navigasi awal, perubahan toko, pembukaan panel pengambilan, pemanggilan halaman, dan pembaruan inventaris. Deteksi harus mengembalikan bukti terstruktur alih-alih boolean sederhana.
from dataclasses import dataclass
@dataclass(frozen=True)
class CaptchaEvidence:
kind: str
website_url: str
website_key: str
async def detect_recaptcha_v2(page) -> CaptchaEvidence | None:
frame = page.locator('iframe[src*="recaptcha"]')
textarea = page.locator('textarea[name="g-recaptcha-response"]')
if await frame.count() == 0 and await textarea.count() == 0:
return None
key = await page.locator('[data-sitekey]').first.get_attribute('data-sitekey')
if not key:
raise RuntimeError("reCAPTCHA detected without a readable site key")
return CaptchaEvidence(
kind="recaptcha_v2",
website_url=page.url,
website_key=key,
)
Inputnya adalah halaman Playwright yang sudah terbuka. Operasi memeriksa dua sinyal widget eksplisit dan membaca kunci situs yang disediakan halaman. Outputnya adalah None atau objek bukti bertipe. Fungsi berhenti dengan kesalahan ketika tantangan terlihat tetapi kunci tidak dapat dikonfirmasi; menebak kunci atau menggunakan kunci dari halaman lain akan membuat pemulihan tidak andal.
Sebelum memanggil solver, validasi bahwa page.url masih milik host ritel yang diizinkan dan bahwa run saat ini masih memiliki identifikasi produk dan toko yang diharapkan. Jika redirect membawa ke halaman akun, checkout, alur pembayaran, atau domain yang tidak terduga, berhenti dan tandai policy_denied. Kemampuan teknis tidak memberikan izin untuk mengakses data pribadi, terbatas, sensitif, atau tidak diizinkan.
Panduan resmi CapSolver reCAPTCHA v2 task mendokumentasikan ReCaptchaV2TaskProxyLess, websiteURL, dan websiteKey. API createTask mengembalikan taskId; API getTaskResult mengembalikan hasil terminal. Hasil reCAPTCHA v2 yang berhasil mencakup solution.gRecaptchaResponse.
import os
import time
import requests
CAPSOLVER_API = "https://api.capsolver.com"
def solve_recaptcha_v2(website_url: str, website_key: str) -> str:
client_key = os.environ["CAPSOLVER_API_KEY"]
created = requests.post(
f"{CAPSOLVER_API}/createTask",
json={
"clientKey": client_key,
"task": {
"type": "ReCaptchaV2TaskProxyLess",
"websiteURL": website_url,
"websiteKey": website_key,
},
},
timeout=30,
).json()
if created.get("errorId") or not created.get("taskId"):
raise RuntimeError(created.get("errorDescription", "createTask failed"))
task_id = created["taskId"]
deadline = time.monotonic() + 120
while time.monotonic() < deadline:
result = requests.post(
f"{CAPSOLVER_API}/getTaskResult",
json={"clientKey": client_key, "taskId": task_id},
timeout=30,
).json()
if result.get("status") == "ready":
token = result.get("solution", {}).get("gRecaptchaResponse")
if not token:
raise RuntimeError("ready result did not contain gRecaptchaResponse")
return token
if result.get("status") == "failed" or result.get("errorId"):
raise RuntimeError(result.get("errorDescription", "CAPTCHA task failed"))
time.sleep(3)
raise TimeoutError("CAPTCHA task exceeded the 120-second deadline")
Input fungsi adalah URL halaman yang diverifikasi dan kunci situs. Operasi membuat tepat satu tugas dan hanya memantau taskId-nya. Outputnya adalah string token yang terdokumentasi. Kondisi berhenti jelas: kesalahan pembuatan tugas, status gagal, respons siap yang tidak lengkap, timeout jaringan, atau tenggat waktu 120 detik. Retry transportasi mungkin mengulang permintaan HTTP untuk hasil tugas yang sama, tetapi tidak boleh secara diam-diam membuat serangkaian tugas yang dikenakan biaya baru.
Klaim Kode Bonus CapSolver Anda
Tingkatkan anggaran otomatisasi Anda secara instan!
Gunakan kode bonus CAP26 saat menambahkan dana ke akun CapSolver Anda untuk mendapatkan tambahan 5% bonus pada setiap pengisian ulang — tanpa batas.
Klaim sekarang di Dasbor CapSolver Anda
Penerapan token bersifat spesifik halaman. Pada integrasi yang diizinkan atau halaman uji yang terkendali, tulis token ke bidang respons yang terdokumentasi dan panggil jalur callback atau pengiriman yang diharapkan halaman. Jangan menyalin token ke browser baru, halaman produk lain, atau konteks toko berbeda.
async def apply_recaptcha_token(page, token: str) -> None:
applied = await page.evaluate(
"""
(token) => {
const fields = [...document.querySelectorAll(
'textarea[name="g-recaptcha-response"]'
)];
if (fields.length === 0) return false;
for (const field of fields) {
field.value = token;
field.innerHTML = token;
field.dispatchEvent(new Event('change', { bubbles: true }));
}
return true;
}
""",
token,
)
if not applied:
raise RuntimeError("bidang respons reCAPTCHA hilang sebelum diterapkan")
Contoh ini secara sengaja dibatasi pada bidang respons yang terlihat di halaman saat ini. Beberapa implementasi juga memerlukan callback yang terdokumentasi. Periksa halaman yang Anda miliki atau diizinkan untuk diuji dan koneksi ke kontrak integrasi nyata miliknya. Jangan pernah membuat nama callback. Setelah aplikasi, tunggu widget atau rute verifikasi untuk berubah status, lalu lanjutkan tindakan inventaris setelahnya.
Verifikasi inventaris harus menghubungkan status yang diamati dengan produk dan toko yang diminta serta menyimpannya. Sebuah pemilih yang mengatakan "tersedia" tidak cukup jika label toko berubah secara diam-diam atau halaman produk mengalihkan ke varian.
from datetime import datetime, timezone
async def read_inventory(page, expected_sku: str, expected_store: str) -> dict:
sku = (await page.locator('[data-product-sku]').first.get_attribute('data-product-sku'))
store = (await page.locator('[data-store-id]').first.get_attribute('data-store-id'))
label = (await page.locator('[data-inventory-status]').first.inner_text()).strip()
if sku != expected_sku or store != expected_store:
raise RuntimeError("konteks produk atau toko berubah selama pengumpulan")
normalized = {
"In stock": "in_stock",
"Limited stock": "limited",
"Out of stock": "out_of_stock",
}.get(label)
if not normalized:
raise RuntimeError(f"label inventaris tidak dikenal: {label!r}")
return {
"product_id": sku,
"store_id": store,
"availability": normalized,
"observed_at": datetime.now(timezone.utc).isoformat(),
"verification": "product-store-status",
}
Pemilih adalah placeholder untuk halaman yang Anda kendalikan atau memiliki izin untuk otomasi. Inputnya adalah halaman saat ini ditambah identifikasi yang diharapkan. Operasi ini memeriksa identitas sebelum mengnormalisasi label. Outputnya adalah catatan inventaris yang diverifikasi. Fungsi ini berhenti jika elemen hilang, identifikasi berubah, atau status tidak dikenal. Henti ini melindungi sistem downstream dari kegagalan umum: mengubah tata letak halaman menjadi peristiwa habis stok palsu.
Untuk produksi, tambahkan saluran bukti kedua ketika tersedia. Contoh termasuk objek produk yang terstruktur, respons XHR yang diinisiasi oleh halaman, label toko panel pengambilan, atau pemeriksaan kelayakan keranjang yang diizinkan oleh perjanjian Anda. Pengumpul harus memerlukan kesepahaman antara bukti identitas dan ketersediaan, bukan permintaan duplikat hanya untuk meningkatkan kepercayaan.
Mesin keadaan yang dapat diprediksi membuat alur kerja teramati dan mencegah pemulihan rekursif.
SCOPED
-> OPEN_PRODUCT
-> CONFIRM_STORE
-> DETECT_CHECKPOINT
-> tidak ada tantangan: READ_INVENTORY
-> reCAPTCHA v2: CREATE_ONE_TASK
-> siap: APPLY_IN_SAME_SESSION
-> gagal/waktu habis: NEEDS_REVIEW
-> tidak didukung/ambiguitas: NEEDS_REVIEW
-> REPLAY_INVENTORY_ACTION_ONCE
-> VERIFY_PRODUCT + STORE + AVAILABILITY
-> valid: WRITE_RECORD
-> tantangan berulang: NEEDS_REVIEW
-> konteks berubah: POLICY_DENIED
Pekerjaan harus membawa satu ID korelasi melalui setiap keadaan. Catat waktu transisi dan hasilnya, tetapi jangan pernah mencatat token yang diselesaikan atau kunci klien. FAQ kesalahan dan pemecahan masalah CapSolver dapat membantu operator membedakan kegagalan penyedia dari kegagalan browser dan aplikasi.
Gejala termasuk kunci situs yang hilang, halaman verifikasi yang tidak terduga, atau keluarga widget yang tidak dikenal oleh adapter. Tangkap screenshot yang telah dihapus dan host tingkat atas, lalu berhenti. Jangan kirim parameter yang ditebak atau anggap setiap iframe sebagai reCAPTCHA.
Nilai errorId yang tidak nol, status gagal, hasil siap yang tidak terstruktur, atau tenggat waktu polling adalah kegagalan batas penyedia. Pertahankan taskId, deskripsi kesalahan yang terdokumentasi, waktu yang telah berlalu, dan ID korelasi. Ulangi hanya jika kelas kesalahan secara eksplisit bersifat sementara dan anggaran tugas yang tersisa memungkinkannya.
Bidang respons mungkin hilang karena halaman berpindah, dirender ulang, atau berubah konteks toko. Jangan menerapkan token ke halaman pengganti secara otomatis. Jalankan kembali pemeriksaan skop dan konteks, lalu mulai ulang pemeriksaan produk tunggal dari keadaan bersih atau arahkan ke tinjauan.
Penyedia dapat mengembalikan tugas siap sementara halaman menolak solusi karena sesi, waktu halaman, metadata widget, atau jalur callback tidak sesuai. Klasifikasikan ini sebagai kegagalan aplikasi. Satu pemulihan yang terkendali sudah cukup. Jika CAPTCHA berulang, berhenti alih-alih memulai loop.
Jika halaman dimuat tetapi bukti stok tidak ada atau bertentangan, catat "unknown", bukan "out_of_stock". Beri peringatan ketika ambiguitas melewati ambang batas untuk retailer atau template, karena sering menunjukkan perubahan markup alih-alih peristiwa inventaris nyata.
Spesifikasi semantik HTTP membantu membedakan status transportasi dari makna aplikasi. "200 OK" hanya menggambarkan respons HTTP; tidak membuktikan bahwa lokasi dipilih, CAPTCHA diterima, atau inventaris dikembalikan.
Otomasi inventaris yang baik meminimalkan pengumpulan sambil memaksimalkan kepercayaan. Lakukan polling dengan frekuensi yang dibenarkan oleh kebutuhan bisnis dan diizinkan oleh sumber. Simpan metadata produk yang stabil. Jadwalkan pemeriksaan toko dengan jitter dalam jendela yang disetujui, bukan permintaan paralel yang tajam. Gunakan pengambilan kondisional di mana sumber mendukungnya, dan hentikan run ketika tingkat tantangan atau tingkat kesalahan aplikasi meningkat secara tidak terduga.
Lacak metrik ini secara terpisah:
Jangan hanya mengoptimalkan untuk penyelesaian solver. Tingkat siap yang tinggi dengan tingkat penerimaan aplikasi yang rendah menunjukkan masalah integrasi. Tingkat penerimaan yang tinggi dengan tingkat inventaris tidak diketahui yang meningkat menunjukkan masalah ekstraktor atau template halaman. Metrik harus menunjukkan lapisan yang bertanggung jawab atas kegagalan.
Ketika data mengirimkan notifikasi, deduplikasi pengamatan yang berulang dan tentukan aturan stabilitas. Misalnya, beri tahu tentang "out_of_stock" hanya setelah dua pemeriksaan valid yang dipisahkan oleh interval pengumpulan normal, sementara transisi "in_stock" mungkin memerlukan pengamatan yang berhasil segar. Pertahankan aturan ini terlihat dalam konfigurasi sehingga tim bisnis dapat meninjau mengapa notifikasi dikirim.
Uji alur kerja terhadap halaman yang Anda miliki atau diizinkan secara eksplisit untuk diotomasi. Gunakan fixture untuk keadaan inventaris biasa dan integrasi CAPTCHA yang terkendali untuk uji pemulihan.
Garis panduan memilih API penyelesaian CAPTCHA memberikan kriteria evaluasi tambahan, tetapi uji penerimaan untuk kasus pengguna ini tetap spesifik bisnis: sistem harus mengembalikan produk yang benar, toko yang benar, dan ketersediaan yang benar setelah pemulihan yang dibatasi.
Pengumpulan data inventaris toko menjadi andal ketika penanganan CAPTCHA diperlakukan sebagai keadaan yang dikendalikan dalam alur kerja ritel yang diverifikasi. Pertahankan konteks produk dan toko, buat satu tugas yang terdokumentasi, terapkan solusi dalam sesi yang diizinkan, ulangi tindakan inventaris sekali, dan terbitkan data hanya setelah pemeriksaan identitas dan ketersediaan berhasil. CapSolver menyediakan infrastruktur tugas CAPTCHA; pengumpul Anda tetap bertanggung jawab atas skop, batas kecepatan, kualitas data, dan kondisi berhenti.
Q: Apa output minimum untuk pengumpulan data inventaris toko?
Output yang dapat dipercaya minimum mencakup ID produk kanonik, ID toko atau wilayah, ketersediaan yang dinormalisasi, waktu pengamatan, dan bukti yang digunakan untuk memverifikasi keadaan. Halaman kosong atau checkpoint gagal tidak boleh diubah menjadi "out_of_stock".
Q: Mengapa sesi browser yang sama harus dipertahankan selama pemulihan CAPTCHA?
Sesi yang sama mempertahankan halaman, cookie, pemilihan produk, pemilihan toko, dan siklus widget yang terkait dengan checkpoint. Memindahkan hasil ke konteks lain dapat menyebabkan penolakan atau menghubungkan pengamatan ke toko yang salah.
Q: Berapa jumlah ulangan CAPTCHA yang harus dilakukan oleh pekerjaan inventaris?
Gunakan anggaran eksplisit kecil: satu tugas dan satu pemulihan aplikasi yang terkendali adalah default yang praktis. Tantangan berulang harus memasuki "needs_review" sehingga integrasi dapat diperiksa tanpa loop mahal atau mengganggu.
Q: Apakah tugas CapSolver yang siap membuktikan bahwa inventaris dikumpulkan?
Tidak. Tugas yang siap hanya membuktikan bahwa penyedia mengembalikan solusi. Browser harus menerimanya, dan aplikasi masih harus mengembalikan produk, toko, dan keadaan inventaris yang dikenal.
Q: Apakah alur kerja ini dapat mengumpulkan inventaris dari portal ritel pribadi?
Hanya ketika pemilik portal secara eksplisit mengizinkan otomasi dan alur kerja mematuhi perjanjian yang berlaku dan hukum. Kemampuan teknis tidak memberikan izin untuk mengakses data pribadi, terbatas, sensitif, atau tidak sah.
Pelajari arsitektur pengambilan data web Rust yang dapat diskalakan dengan reqwest, scraper, pengambilan data asinkron, pengambilan data browser tanpa tampilan, rotasi proxy, dan penanganan CAPTCHA yang sesuai aturan.

Mengotomasi penyelesaian CAPTCHA dengan Nanobot dan CapSolver. Gunakan Playwright untuk menyelesaikan reCAPTCHA dan Cloudflare secara otomatis.
