
Emma Foster
Machine Learning Engineer

Sebuah agen AI dapat menerima catatan yang terlihat valid dari halaman yang salah. Layar masuk mungkin berisi judul, dokumen yang tidak lengkap mungkin diproses dengan sukses, dan model mungkin mengembalikan JSON bahkan ketika fakta yang diminta hilang. Arsitektur pengambilan data agen AI memerlukan keputusan terpisah untuk mencapai sumber dan memahami isinya.
Tutorial ini merancang batas tersebut di sekitar snapshot yang tidak dapat diubah dan kontrak catatan yang diberi versi. Alur kerja ini berlaku untuk pengumpulan yang diizinkan dari pengumuman publik, pembaruan dokumentasi, dan informasi web lain yang diperbolehkan. CapSolver muncul sebagai kemampuan penanganan CAPTCHA yang didukung di lapisan akses. Contoh yang dapat dijalankan kemudian menunjukkan cara mengklasifikasikan hasil pengumpulan, mengekstrak himpunan catatan kecil, dan menyimpan bukti ketika validasi gagal.
Lapisan akses harus mengembalikan snapshot yang dapat digunakan atau kegagalan yang jelas; lapisan ekstraksi harus mengembalikan catatan kandidat yang terkait dengan snapshot tersebut. Pertahankan kedua kontrak tetap stabil meskipun runtime browser, parser, atau model berubah.
Pipeline adalah: permintaan pengumpulan yang disetujui → adapter akses → snapshot yang disimpan → adapter ekstraksi → validasi → penyimpanan catatan yang diterima → agen. Dalam desain ini, ekstraksi dapat dijalankan kembali dari bukti yang disimpan tanpa membuka browser kembali.
Berikan adapter akses sumber yang disetujui, identitas tugas, anggaran waktu, dan konteks sesi yang diizinkan. Tugasnya termasuk memilih representasi yang diperlukan, menunggu konten yang relevan, mempertahankan kepemilikan sesi, dan mengklasifikasikan kegagalan. Konfigurasi jaringan dan rendering JavaScript termasuk dalam infrastruktur HTTP atau browser Anda.
Output harus mencatat lokasi sumber yang diminta dan akhir, waktu pengamatan, jenis representasi, hash konten, dan bukti kesiapan. Hindari bendera "sukses" tunggal yang menyembunyikan halaman yang sebenarnya dimuat. URL akhir dan status HTTP membantu, tetapi identitas dokumen yang diharapkan dan wilayah konten yang diperlukan juga perlu diperiksa.
Berikan ekstraktor referensi snapshot, versi skema, dan definisi bidang. Jangan secara diam-diam menavigasi, mengubah kredensial, atau memilih jalur jaringan lain. Kembalikan bidang yang hilang atau ambigu secara eksplisit alih-alih meminta lapisan akses untuk terus mencoba hingga nilai muncul.
Glosarium pengambilan data AI menjelaskan penggunaan AI yang lebih luas dalam mengumpulkan dan memahami informasi web. Batas ini juga mendukung ekstraksi deterministik: atribut yang stabil atau data terstruktur yang terdokumentasi mungkin cukup. Gunakan model ketika interpretasi diperlukan, sambil mempertahankan kontrak validasi yang sama di hilir.
Snapshot yang dapat digunakan harus berisi bukti yang diperlukan untuk bidang yang diminta, dalam representasi yang dapat dipahami oleh ekstraktor. Pilih HTML, DOM yang dirender, atau screenshot sesuai kebutuhan.
HTML mentah cocok ketika respons sudah berisi konten yang relevan. Jika bidang yang diperlukan hanya muncul setelah eksekusi sisi klien, adapter browser harus menangkap DOM yang dirender setelah pemeriksaan kesiapan khusus tugas. Tetapkan kesiapan sebagai kondisi yang dapat diamati, seperti kontainer catatan yang diharapkan dan tanda selesai, bukan tidur tetap universal.
Catat jenis representasi yang ditangkap. Parser yang diuji pada markup yang dirender tidak boleh menerima cangkang HTML awal tanpa perubahan kontrak yang jelas. Jika wilayah yang diperlukan tidak ada, klasifikasikan snapshot sebagai tidak lengkap sebelum mencoba ekstraksi.
Screenshot menyediakan piksel dari viewport tertentu pada waktu tertentu. Untuk ekstraksi berbasis screenshot, simpan dimensi gambar, konteks pengambilan, dan referensi wilayah untuk setiap bidang yang diekstrak. Jika nilai berada di luar tampilan yang ditangkap, kembalikan sebagai hilang; keahlian model tentang tata letak serupa bukanlah bukti untuk nilai tersebut.
Jangan ubah estimasi visual menjadi angka pasti tanpa mencatat ketidakpastian. Di mana baik DOM maupun bukti visual tersedia, gunakan ketidaksesuaian sebagai kasus tinjauan. Contoh di bawah hanya mengimplementasikan adapter HTML; adapter visi akan memerlukan pemeriksaan bukti dan set evaluasi sendiri.
Keputusan ulangi harus menyebutkan lapisan yang gagal, manfaat yang diharapkan dari upaya lain, dan anggaran yang tersisa. Pertahankan ulangi pengumpulan dan interpretasi terpisah agar kesalahan ekstraksi tidak menciptakan lalu lintas yang tidak terkendali.
| Pengamatan | Lapisan yang bertanggung jawab | Tindakan yang direkomendasikan |
|---|---|---|
| Waktu habis untuk membaca atau kesalahan layanan sementara yang dipilih | Akses | Ulangi hanya baca yang diizinkan dalam anggaran waktu dan upaya |
| HTTP 429 atau penundaan yang diminta layanan | Akses | Tunda ke pengatur bersama dan pertahankan sinyal penundaan |
| HTTP 401/403 atau otorisasi yang tidak jelas | Akses | Hentikan dan tinjau jalur akses yang diizinkan |
| Tantangan CAPTCHA yang dikenali | Akses | Berhenti sementara untuk tinjauan kelayakan dan tugas yang didukung |
| Jawaban kosong, dokumen salah, atau wilayah yang diperlukan hilang | Akses | Simpan bukti diagnostik dan selidiki kesiapan |
| Bidang hilang, tanggal tidak valid, catatan duplikat, atau ketidakcocokan skema | Ekstraksi/validasi | Kategorikan kandidat dan ulangi terhadap snapshot |
| Bentuk yang valid tetapi makna tidak didukung | Validasi | Tolak atau minta tinjauan; jangan anggap teks lancar sebagai bukti |
Semantik HTTP penting saat mengimplementasikan baris pertama. Aturan ulangi dan idempotensi RFC 9110 membedakan operasi yang dapat diulang dengan aman dari operasi yang efeknya mungkin tidak pasti. Jangan gunakan loop ulangi baca untuk pengiriman formulir atau tindakan lain yang mengubah status.
Header Retry-After dapat menyatakan penundaan atau tanggal HTTP. Pertahankan nilai tersebut untuk pengaturan. Seorang pekerja lokal tidak boleh mengganti penundaan yang diminta server dengan backoff yang lebih pendek, dan pekerja yang berbagi lingkup pengumpulan yang sama harus berbagi status penundaan.
CapSolver harus menangani hanya tugas CAPTCHA yang terdokumentasi setelah alur kerja Anda telah menetapkan izin, kompatibilitas tugas, dan konteks sesi yang diperlukan. Respons 403, halaman kosong, dan widget CAPTCHA adalah pengamatan yang berbeda; hindari memetakan semuanya ke permintaan penyelesaian.
Kontrak createTask CapSolver memerlukan objek tugas yang sesuai. Untuk pekerjaan asinkron, getTaskResult mengembalikan status dan output tugas. Adapter akses tetap bertanggung jawab atas penerapan integrasi yang terdokumentasi dan pemeriksaan tujuan setelahnya.
Tugas yang selesai bukanlah snapshot halaman yang divalidasi. Periksa kembali identitas dokumen dan kondisi kesiapan sebelum menyerahkan konten ke ekstraksi. Tetapkan anggaran tantangan terpisah dan hentikan ketika tantangan tidak didukung, otorisasi tidak jelas, atau halaman yang diharapkan tetap tidak tersedia. Tumpukan infrastruktur browser agen AI memberikan panduan terkait tentang kepemilikan runtime dan bukti sesi.
Tukarkan 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.
Tukarkan sekarang di Dashboard CapSolver Anda
Alur kerja Python berikut mengklasifikasikan jawaban akses sintetis, menyimpan HTML yang diterima, mengekstrak bidang pengumuman, dan mengembalikan JSON yang strukturnya. Simpan sebagai pipeline_example.py dan jalankan dengan Python 3.9 atau lebih baru; hanya menggunakan perpustakaan standar.
Fungsi fetch adalah adapter baca saja yang diinjeksikan. Di sini menyediakan data uji dalam memori, dan demonstrasi menonaktifkan tidur. Tidak ada situs web, layanan browser, model, atau API CAPTCHA yang dihubungi. Bidang challenge dan ready mewakili pengamatan yang disediakan oleh adapter akses; contoh tidak mengimplementasikan detektor tantangan universal.
Parser menggunakan panggilan kembali HTMLParser Python untuk kontrak markup yang sengaja kecil: setiap article berisi satu h2, ID catatan, dan tanggal publikasi. Bukan parser DOM umum atau validator untuk HTML yang tidak lengkap.
from dataclasses import dataclass
from datetime import date
from hashlib import sha256
from html.parser import HTMLParser
import json
import time
class PipelineError(Exception):
def __init__(self, stage, reason, retry_after=""):
self.stage, self.reason = stage, reason
self.retry_after = retry_after
super().__init__(f"{stage}:{reason}")
@dataclass(frozen=True)
class Reply:
status: int
body: str = ""
content_type: str = "text/html"
challenge: bool = False
ready: bool = True
retry_after: str = ""
def access(fetch, wait=time.sleep):
# fetch is a read-only adapter; all values below are application policy.
for attempt in range(2):
try:
reply = fetch()
except TimeoutError:
if attempt == 0:
wait(0.5)
continue
raise PipelineError("access", "timeout_exhausted")
if reply.status == 429:
# Pass Retry-After to a shared scheduler; do not retry here.
raise PipelineError("access", "defer_rate_limit", reply.retry_after)
if reply.status in (401, 403):
raise PipelineError("access", "authorization_review")
if reply.challenge:
raise PipelineError("access", "challenge_review")
if reply.status == 503 and reply.retry_after:
raise PipelineError("access", "defer_service", reply.retry_after)
if reply.status in (502, 503, 504) and attempt == 0:
wait(0.5)
continue
if reply.status != 200:
raise PipelineError("access", "http_status")
if reply.content_type.split(";")[0].strip().lower() != "text/html":
raise PipelineError("access", "representation_mismatch")
if not reply.ready or not reply.body.strip():
raise PipelineError("access", "incomplete_snapshot")
return reply.body
raise PipelineError("access", "attempts_exhausted")
class BulletinParser(HTMLParser):
# This small parser supports only the documented fixture markup.
def __init__(self):
super().__init__(convert_charrefs=True)
self.rows, self.current, self.in_title = [], None, False
def handle_starttag(self, tag, attrs):
attrs = dict(attrs)
if tag == "article":
if self.current is not None:
raise PipelineError("extraction", "nested_record")
self.current = {"id": attrs.get("data-id", ""),
"published": attrs.get("data-published", ""),
"title_parts": [], "title_count": 0}
elif tag == "h2" and self.current is not None:
self.current["title_count"] += 1
self.in_title = True
def handle_data(self, data):
if self.current is not None and self.in_title:
self.current["title_parts"].append(data)
def handle_endtag(self, tag):
if tag == "h2":
self.in_title = False
if tag == "article" and self.current is not None:
self.rows.append(self.current)
self.current, self.in_title = None, False
def extract(html):
parser = BulletinParser()
parser.feed(html)
parser.close()
if parser.current is not None or not parser.rows:
raise PipelineError("extraction", "record_structure")
records, seen = [], set()
for row in parser.rows:
title = " ".join("".join(row["title_parts"]).split())
if not row["id"].strip() or not title or row["title_count"] != 1:
raise PipelineError("extraction", "required_field")
try:
published = date.fromisoformat(row["published"]).isoformat()
except ValueError:
raise PipelineError("extraction", "invalid_date")
if row["id"] in seen:
raise PipelineError("extraction", "duplicate_id")
seen.add(row["id"])
records.append({"id": row["id"], "title": title,
"published": published})
return records
def run(fetch, archive, wait=time.sleep):
html = access(fetch, wait)
digest = sha256(html.encode("utf-8")).hexdigest()
archive[digest] = html # In-memory evidence retained even if parsing fails.
records = extract(html)
return {"schema_version": "bulletins.v1", "source_id": "fixture:bulletins",
"snapshot_sha256": digest,
"records": records}
if __name__ == "__main__":
html = ('<article data-id="notice-1" data-published="2026-09-10">'
'<h2>Maintenance window announced</h2></article>')
replies = iter([Reply(503), Reply(200, html)])
archive = {}
output = run(lambda: next(replies), archive, wait=lambda seconds: None)
print(json.dumps(output, indent=2))
Demonstrasi menerima 503 sintetis diikuti oleh jawaban HTML yang layak. Ia menghasilkan hasil berikut:
{
"schema_version": "bulletins.v1",
"source_id": "fixture:bulletins",
"snapshot_sha256": "6ed8df5a98ee53e2889feb5ef7ed4dd8d549dba82882580418d4ca9656b7d46b",
"records": [
{
"id": "notice-1",
"title": "Maintenance window announced",
"published": "2026-09-10"
}
]
}
Setiap catatan harus memiliki ID, satu judul yang tidak kosong, dan tanggal yang dapat diproses. ID duplikat akan menolak batch. Digest snapshot menghubungkan output dengan HTML yang disimpan, dan kesalahan ekstraksi menyimpan HTML tersebut di arsip yang dikelola pengguna untuk pemutaran ulang.
Batas ulang sebanyak dua kali dan jeda setengah detik adalah kebijakan aplikasi contoh, bukan rekomendasi penyedia. Loop menunda 429 secara langsung, mempertahankan pendinginan 503, dan berhenti pada otorisasi atau tinjauan tantangan. Kegagalan dalam extract tidak dapat memanggil fetch lagi.
Implementasikan penerimaan sumber, pemeriksaan redirect, dekoding konten yang didukung, timeout per permintaan, dan tenggat waktu keseluruhan sebelum menghubungkan contoh ke transport yang sebenarnya. fetch yang sinkron yang tidak pernah kembali tidak dibatasi oleh penghitung percobaan. Kirim tenggat waktu yang tersisa ke transport dan masukkan jeda ulang ke dalam anggaran tersebut.
Ganti arsip memori dengan penyimpanan terkendali, dan tambahkan waktu pengamatan, identitas sumber aktual, versi ekstraktor, dan versi skema ke metadata-nya. Terapkan batas ukuran sebelum dekoding atau parsing. Snapshot yang gagal atau tidak lengkap mungkin masih menjadi bukti diagnostik yang berguna, tetapi pisahkan dari kumpulan snapshot yang layak diekstraksi.
Data yang diterima memerlukan pemeriksaan makna dan cakupan selain struktur JSON. Contoh ini memvalidasi kontrak kecil yang pasti; layanan ekstraksi umum memerlukan kebijakan penerimaan yang lebih kaya.
Mulai dengan definisi bidang. Tanggal publikasi, tanggal pembaruan, dan waktu pencatatan menggambarkan peristiwa yang berbeda. Tetapkan yang mana yang dibutuhkan agen dan tolak substitusi. Untuk bidang yang dihasilkan model, kaitkan dengan span sumber atau wilayah visual dan periksa apakah bukti mendukung makna bidang tersebut. Kata yang cocok di halaman tidak cukup kuat untuk bidang seperti harga, ketersediaan, atau tanggal.
Periksa kelengkapan pada tingkat pencatatan. Array kosong bisa berarti "tidak ada catatan", perubahan tata letak, paginasi tidak lengkap, atau kegagalan ekstraksi. Terima hasil kosong hanya ketika sumber menyediakan keadaan kosong yang eksplisit dan diverifikasi. Fixture menolak daftar kosong karena tidak memiliki kontrak seperti itu.
Tentukan jendela keterbaruan untuk tugas tersebut. Mengulang ekstraksi snapshot lama mungkin memperbaiki masalah parser, tetapi tidak membuat pengamatan dasar menjadi terkini. Sertakan identitas snapshot dan versi ekstraktor/skema dalam kunci pemutaran ulang, lalu terbitkan catatan yang diterima melalui operasi penyimpanan idempoten. Pertahankan kandidat yang ditolak tersedia untuk tinjauan diagnostik terbatas alih-alih mencampurnya ke dataset kerja agen.
Anggap konten halaman sebagai input yang tidak tepercaya sepanjang waktu. Panduan injeksi prompt OWASP menjelaskan risiko dari instruksi yang terbenam dalam konten eksternal. Pisahkan alat ekstraksi dari kredensial dan tindakan konsekuensial; teks sumber tidak boleh memperoleh otoritas untuk mengubah cakupan pengumpulan atau mengirim data ke tempat lain.
Uji batas harus memverifikasi hasil yang diperoleh dan ketiadaan pekerjaan tambahan yang tidak diinginkan. Tes parser yang berhasil saja tidak membuktikan bahwa lapisan akses berhenti dengan benar.
Untuk contoh ini, uji timeout diikuti oleh keberhasilan, kesalahan sementara berulang, respons 200 yang ditandai sebagai tantangan, 429 dengan jeda, representasi yang tidak didukung, judul yang hilang, tanggal tidak valid, dan ID duplikat. Hitung panggilan adapter: kasus tantangan harus berhenti setelah satu panggilan, dan kegagalan parsing harus mempertahankan snapshot tanpa upaya akses lain.
Rangkaian pengujian lokal yang menyertai lulus 21 tes untuk pipeline fixture, termasuk kehabisan ulang, pemeliharaan jeda, penyimpanan snapshot, dan pemutaran ulang yang pasti. Ini adalah pemeriksaan perangkat lunak sintetis, bukan tingkat keberhasilan sumber langsung atau benchmark ekstraksi model.
Sebelum pemasangan, tambahkan sumber staging kecil yang diperbolehkan dan uji kesiapan rendering nyata, penanganan redirect, kedaluwarsa sesi, pembatalan transport, dan bukti output. Ukur snapshot yang layak dan catatan yang diterima secara terpisah. Pemisahan ini memberi tahu Anda apakah harus meningkatkan pengumpulan atau interpretasi ketika tingkat penerimaan akhir berubah.
Arsitektur agen AI web scraping menjadi lebih mudah dioperasikan ketika setiap tahap memiliki output yang teramati dan pemilik yang jelas. Pertahankan kontrak akses fokus pada snapshot yang layak, kontrak ekstraksi fokus pada bidang kandidat, dan validasi fokus pada bukti, kelengkapan, dan keterbaruan.
Mulai dengan alur kerja lokal, latih jalur negatif, dan hubungkan sumber yang diperbolehkan hanya setelah batas adapter jelas. Untuk alur kerja yang membutuhkan penanganan CAPTCHA yang terdokumentasi, evaluasi CapSolver dalam batas akses tersebut dan verifikasi tujuan sebelum ekstraksi dilanjutkan.
Q: Apa perbedaan antara lapisan akses web dan lapisan ekstraksi data?
Lapisan akses mendapatkan snapshot halaman yang layak dan mengklasifikasikan kegagalan pengambilan. Lapisan ekstraksi menginterpretasikan snapshot tersebut menjadi bidang kandidat. Pemeriksaan penerimaan terpisah menentukan apakah catatan yang dihasilkan layak untuk agen.
Q: Apakah model AI menerima HTML, snapshot DOM, atau screenshot?
Gunakan representasi yang berisi bukti untuk bidang yang diminta. HTML bisa cocok untuk konten yang disediakan server, DOM yang dirender bisa menangkap konten sisi klien, dan screenshot bisa mendukung interpretasi visual dengan referensi wilayah dan pemeriksaan ketidakpastian.
Q: Apakah bidang yang hilang menyebabkan permintaan halaman baru?
Bidang yang hilang sebaiknya terlebih dahulu memicu tinjauan atau pengulangan ekstraksi snapshot yang disimpan. Minta halaman baru hanya ketika bukti menunjukkan snapshot tidak lengkap atau usang dan kebijakan akses memperbolehkan upaya lain.
Q: Di mana CapSolver masuk dalam arsitektur ini?
CapSolver masuk di belakang antarmuka tugas CAPTCHA yang didukung dalam lapisan akses untuk alur kerja yang diizinkan. Aplikasi Anda memiliki kelayakan tugas, konteks sesi, batas percobaan ulang, dan validasi tujuan setelah tugas selesai.
Q: Apakah contoh Python melakukan web scraping AI langsung?
Tidak. Contoh ini menjalankan pipeline dengan fixture HTML secara lokal dan menguji kontraknya. Deployment langsung harus menambahkan adapter akses yang diperbolehkan; ekstraksi berbasis model atau visual juga memerlukan implementasi sendiri dan evaluasi berbasis bukti.
Evaluasi layanan CAPTCHA perusahaan dengan uji coba terfokus yang mencakup kesesuaian tugas, hasil yang diterima, pengalokasian biaya, bukti keamanan, dan dukungan.

Gunakan checklist server MCP produksi untuk meninjau izin alat, isolasasi tenant, masukan, penanganan kegagalan, log, dan bukti rilis sebelum penerapan.
