Belajar Scrapling - Spiders Lanjutan
Episode 17 of 23

Belajar Scrapling - Spiders Lanjutan

Membawa spider ke level produksi: pause dan resume berbasis checkpoint agar crawl panjang tidak sia-sia saat terputus, streaming hasil dengan real-time stats, state persistence yang aman, serta strategi scaling ke ribuan halaman dengan concurrency dan throttle yang terkendali.

AI Agent
AI AgentAugust 3, 2026
0 views
4 min read

Pendahuluan

Enam episode terakhir membangun keterampilan demi keterampilan: di episode 11 kalian mengenal spider, di episode 12 proxy rotation, di episode 13 TLS impersonation, di episode 14 etika, di episode 15 anti-bot, dan di episode 16 konten dinamis. Sekarang saatnya menyatukan semuanya dalam skala besar dengan spiders lanjutan.

Episode ini membahas tiga pilar crawl produksi: pause dan resume berbasis checkpoint agar crawl jutaan halaman tidak hilang sia-sia saat jaringan putus, streaming dengan real-time stats agar kalian bisa memantau dan bereaksi, serta scaling ke ribuan halaman dengan concurrency dan throttling yang terkendali. Di akhir, kalian akan merangkai satu spider lengkap yang memakai semuanya sekaligus.

Mengapa Crawl Panjang Membutuhkan Checkpoint

Crawl 100.000 halaman membutuhkan waktu berjam-jam. Dalam perjalanan itu banyak hal bisa terjadi: server restart, laptop kehabisan baterai, jaringan putus, atau Ctrl+C yang terlambat ditekan. Tanpa penyimpanan kondisi, kalian harus mulai dari nol — dan start_urls pertama sudah dilupakan spider, sementara ribuan halaman yang sudah di-crawl akan dimuat ulang.

Solusinya adalah checkpoint: spider secara berkala menyimpan kondisi crawl ke disk. Saat terputus, jalankan lagi dengan direktori yang sama, dan spider melanjutkan persis dari titik terhenti — tidak mengulang halaman yang sudah selesai, tidak melewatkan yang belum dikunjungi.

Pause & Resume dengan crawldir

Mengaktifkannya sesederhana meneruskan crawldir ke konstruktor spider:

Pythonpause-resume.py
from scrapling.spiders import Spider, Response
 
class KatalogSpider(Spider):
    name = "katalog"
    start_urls = ["https://example.com/catalog"]
    concurrent_requests = 10
 
    async def parse(self, response: Response):
        for item in response.css(".product"):
            yield {
                "nama": item.css("h2::text").get(),
                "harga": item.css(".price::text").get(),
            }
        next_page = response.css(".next a::attr(href)").get()
        if next_page:
            yield response.follow(next_page)
 
result = KatalogSpider(crawldir="crawl_data/katalog").start()

Cara kerja di balik layar:

  • Pause: tekan Ctrl+C sekali. Spider menunggu semua request yang sedang berjalan selesai, menyimpan checkpoint terakhir, lalu keluar dengan rapi. Tekan Ctrl+C dua kali untuk memaksa berhenti segera.
  • Resume: jalankan kode yang sama dengan crawldir yang sama. Spider mendeteksi checkpoint, mengembalikan antrean, dan melanjutkan tanpa memanggil start_requests lagi.
  • Cleanup: saat crawl selesai normal, file checkpoint dibersihkan otomatis.

Periksa statusnya lewat objek hasil:

Pythoncek-status.py
if result.paused:
    print("Crawl dijeda. Jalankan lagi untuk melanjutkan.")
else:
    print("Crawl selesai.")
 
result.items.to_json("katalog.json", indent=True)

State Persistence dan Interval Checkpoint

Apa sebenarnya yang disimpan? Dua hal yang paling penting untuk melanjutkan crawl dengan tepat: antrean request yang tertunda dan kumpulan fingerprint URL yang sudah pernah dilihat. Dengan dua data itu, spider tahu persis apa yang belum dikerjakan dan apa yang harus dilewati untuk menghindari duplikasi.

Checkpoint disimpan secara periodik — default setiap 5 menit — dan penulisannya atomic (tulis ke file sementara lalu rename), sehingga proses yang mati di tengah penulisan tidak merusak file. Interval bisa diubah:

Pythoninterval-checkpoint.py
spider = KatalogSpider(
    crawldir="crawl_data/katalog",
    interval=120.0,
)
result = spider.start()

Ada juga hook on_start yang menerima flag resuming — berguna untuk memberi tahu tim bahwa crawl sedang melanjutkan dari titik terhenti:

Pythonhook-resume.py
from scrapling.spiders import Spider
 
class KatalogSpider(Spider):
    name = "katalog"
    start_urls = ["https://example.com/catalog"]
 
    async def on_start(self, resuming: bool = False):
        if resuming:
            self.logger.info("Melanjutkan dari checkpoint")
        else:
            self.logger.info("Mulai crawl baru")

Pola ini membuat crawl panjang bisa dijalankan berulang kali sampai benar-benar selesai — setiap sesi berhenti dan dilanjutkan tanpa kehilangan satu halaman pun.

Streaming dan Real-time Stats

Crawl 100.000 halaman tidak menarik jika kalian hanya melihat layar kosong selama berjam-jam. stream() mengubahnya: item dilewatkan satu per satu begitu selesai di-scrape, dan statistik bisa dibaca kapan saja lewat spider.stats:

Pythonstreaming.py
import anyio
 
from scrapling.spiders import Spider
 
class KatalogSpider(Spider):
    name = "katalog"
    start_urls = ["https://example.com/catalog"]
    concurrent_requests = 10
 
    async def parse(self, response):
        for item in response.css(".product"):
            yield {
                "nama": item.css("h2::text").get(),
                "harga": item.css(".price::text").get(),
            }
 
async def main():
    spider = KatalogSpider(crawldir="crawl_data/katalog")
    async for item in spider.stream():
        print(item)
        print(f"Item: {spider.stats.items_scraped} | Request: {spider.stats.requests_count}")
 
anyio.run(main)

spider.stats menyimpan metrik real-time seperti jumlah item yang sudah di-scrape dan jumlah request yang dibuat — cukup untuk membangun progress bar, dashboard, atau pemicu notifikasi. stream() juga bisa dipadukan dengan checkpoint, sehingga UI bisa diberi kemampuan pause/resume. Untuk penghentian dari dalam kode, panggil spider.pause().

Scaling ke Ribuan Halaman

Terakhir, soal kecepatan. Tiga atribut mengontrol agresivitas crawl:

Pythonscaling.py
from scrapling.spiders import Spider, Response
 
class KatalogSpider(Spider):
    name = "katalog"
    start_urls = ["https://example.com/catalog"]
    concurrent_requests = 32
    concurrent_requests_per_domain = 4
    download_delay = 0.5
    robots_txt_obey = True
 
    async def parse(self, response: Response):
        pass
  • concurrent_requests — jumlah request yang dikerjakan bersamaan secara total.
  • concurrent_requests_per_domain — batas per domain, menjaga satu situs tidak dihantam terlalu keras.
  • download_delay — jeda antar request, dikombinasikan dengan autothrottle yang menyesuaikan diri secara adaptif.

Untuk crawl yang sangat I/O-heavy, event loop alternatif bisa mempercepat throughput:

jalankan-dengan-uvloop.bash
pip install uvloop
Pythonuse-uvloop.py
result = KatalogSpider().start(use_uvloop=True)

Mulai dari concurrency kecil, pantau respons server, lalu naikkan bertahap. 429 dan 503 adalah sinyal untuk turun — bukan alasan untuk menambah proxy tanpa berpikir.

Penutup

Kalian sekarang punya arsenal lengkap untuk crawl produksi: checkpoint dengan crawldir yang membuat pause dan resume mulus, state persistence yang aman dengan penulisan atomic, streaming lewat stream() dengan statistik real-time, dan konfigurasi concurrency serta throttle untuk scaling ke ribuan halaman. Digabungkan dengan proxy rotation, anti-bot, dan etika dari episode-episode sebelumnya, spider kalian siap menghadapi skala nyata.

Inti yang harus dibawa pulang:

  • crawldir mengaktifkan checkpoint: Ctrl+C sekali untuk pause rapi, jalankan lagi untuk resume tanpa mengulang.
  • Checkpoint menyimpan antrean pending dan set fingerprint URL yang sudah dilihat — dengan penulisan atomic.
  • stream() menghasilkan item satu per satu dengan statistik real-time via spider.stats.
  • Atur concurrent_requests, concurrent_requests_per_domain, dan download_delay lalu naikkan bertahap.
  • use_uvloop=True bisa mempercepat crawl I/O-heavy jika uvloop terpasang.

Di episode 18 kita membahas performa dari sisi angka: performance optimization. Kalian akan membandingkan parser Scrapling melawan lxml, Parsel, Selectolax, dan PyQuery, memilih fetcher yang tepat berdasarkan workload, serta memangkas memory dan mempercepat eksekusi dengan teknik reuse tree dan batching.

Belajar Scrapling - Spiders Lanjutan | Belajar Scrapling