84 bintang di GitHub dan terus bertambah. Yozh Crawler + Scraper adalah perangkat lunak gratis, sumber terbuka, dan dikembangkan secara terbuka — berikan kami bintang jika alat ini layak masuk ke dalam tumpukan teknologi Anda.
CyberYozh Data / Yozh Crawler
Perangkat Lunak · Yozh Crawler

Cukup masukkan satu URL sumber, seluruh situs pun langsung ditayangkan

Yozh Crawler menjelajahi sebuah situs mulai dari satu URL dan mengalirkan setiap halaman yang ditemukan melalui SSE. Alat ini menangani bagian tersulit dari proses crawling — penjelajahan awal, penghapusan duplikat, cakupan, etika akses, dan upaya ulang — sementara setiap proses pengambilan halaman dilakukan melalui Yozh Scraper. Tanpa duplikasi Playwright, tanpa SaaS, berjalan di :8001.

$curl -N :8001/api/v1/crawl -d '{"seed_url":"https://site.com", "scope":{"mode":"same-domain","max_depth":2,"max_pages":500}}'

Crawling

Yozh Crawler menjelajahi sebuah situs mulai dari satu URL awal dan mengalirkan setiap halaman yang ditemukan melalui SSE. Yozh Crawler bertanggung jawab atas proses penemuan — penjelajahan awal, penghapusan duplikat, cakupan, ekstraksi tautan, upaya ulang, dan etika akses — sementara pengambilan setiap halaman diserahkan kepada Yozh Scraper melalui HTTP. Hanya ada satu stack Playwright yang perlu dioperasikan, dan setiap fitur scraper (proxy, stealth, sesi, aturan ekstraksi) juga berlaku untuk halaman yang di-crawl.

  • Predikat cakupansame-domain / subdomains / all / regex, dengan pola include & exclude serta batas atas dan bawah yang tetap max_depth / max_pages batas atas yang tetap.
  • Penghapusan duplikat berdasarkan sidik jari — URL-URL dikanonisasikan lalu di-hash (SHA1) sehingga permintaan yang urutannya diubah dan varian dengan tanda garis miring di akhir digabungkan menjadi satu kunjungan.
  • Sistem round-robin per-domain — satu host yang lambat atau berukuran besar tidak dapat menghabiskan kuota pekerja yang seharusnya dialokasikan untuk host lainnya.
  • Pembatas laju adaptif — sebuah token bucket global per domain (dengan jitter) yang digunakan bersama oleh semua pekerjaan; 429 mengurangi setengah RPS selama periode pendinginan.
  • Kondisi sesi — Sistem penilaian ala Crawlee: 401/403/429 menghentikan sesi, kesalahan meningkatkan skornya, keberhasilan menurunkan skornya; melakukan rotasi saat skor ≥ 3 atau setelah 50 kali penggunaan.
  • Streaming SSE — setiap tugas menghasilkan stats, page, page_error, dan acara done / cancelled . Tindaklanjuti temuan segera setelah muncul.
URL Dasarhttp://localhost:8001
Dokumentasi OpenAPIhttp://localhost:8001/docs
Titik akhir MCPhttp://localhost:8001/mcp
Layanan pendamping. Crawler mendelegasikan setiap proses pengambilan data ke Yozh Scraper, jadi jalankan keduanya secara bersamaan — scraper di :8000 dan crawler di :8001.

Mulai cepat

Crawler tersebut dihubungkan ke root docker-compose.yml dan muncul bersamaan dengan scraper:

bash
docker compose up --build
# scraper  → http://localhost:8000
# crawler  → http://localhost:8001

Atau jalankan secara lokal tanpa Docker — arahkan SCRAPER_URL ke scraper yang sedang berjalan:

bash
cd yozh-crawler
pip install -r requirements.txt
cp .env.example .env          # edit SCRAPER_URL if needed
python -m uvicorn src.main:app --reload --port 8001

Penggunaan dasar

Kirim permintaan perayapan dengan seed_url dan sebuah scope. Panggilan tersebut langsung mengembalikan job_id segera; proses perayapan kemudian berjalan di latar belakang melalui tugas-tugas pekerja.

cURL
curl -X POST http://localhost:8001/api/v1/crawl 
  -H "Content-Type: application/json" 
  -d '{
    "seed_url": "https://example.com",
    "scope": {"mode": "same-domain", "max_depth": 2, "max_pages": 50,
              "per_domain_rps": 1.0, "per_domain_concurrency": 1},
    "scrape_options": {"proxy_type": "none"},
    "enable_scraping": false
  }'

Responsnya hanyalah handle tugas:

JSON
{ "job_id": "crawl_abc123" }

Dari sini, Anda bisa menonton siaran langsung acara atau mengakses data lengkapnya.

Penemuan vs panen — tombol enable_scraping toggle

Mesin perayapan yang sama beroperasi dalam dua arah. Sebuah nilai boolean menentukan pilihan antara pemetaan penemuan yang efisien dan pengumpulan data dengan muatan penuh — dan setiap mode menggunakan konfigurasi proxy-nya sendiri, sehingga tidak terjadi tumpang tindih.

enable_scraping: false

Peta penjelajahan

Proses pemindaian ringan. Scraper tetap memproses setiap halaman (sehingga tautan yang dibuat dengan JavaScript dapat terdeteksi), namun crawler hanya menyimpan kerangka dasarnya — sangat cocok untuk peta situs, audit tautan, dan deteksi perubahan.

  • Menjaga url · parent_url · depth · status · took_ms
  • Menampilkan HTML mentah, tangkapan layar, dan data yang diekstraksi
  • Menggunakan yang lebih murah crawl_proxy
  • Muatan terkecil, kecepatan merayap tercepat
enable_scraping: true

Panen penuh

Setiap halaman yang dikunjungi disimpan beserta ScrapeResponse — HTML mentah, tangkapan layar (opsional), serta bidang apa pun dari aturan ekstraksi Anda. Lakukan perayapan dan penataan dalam satu proses.

  • Menampilkan isi lengkap ScrapeResponse per halaman
  • raw_html · screenshot · diekstraksi data
  • Kegunaan scrape_options.proxy_*
  • Lolos extract aturan untuk menghasilkan JSON yang bersih
Pemilihan proxy. crawl_proxy hanya digunakan jika enable_scraping=false; scrape_options.proxy_* digunakan ketika true. Jika crawl_proxy adalah null, scrape_options proksi akan digunakan terlepas dari mode yang digunakan.

Cakupan perayapan

Cakupan menentukan batasan proses perayapan: di mana proses perayapan diperbolehkan berjalan, dan seberapa intens proses perayapan diperbolehkan mengakses setiap host. Ini adalah scope objek pada permintaan tersebut.

BidangTipeBawaanDeskripsi
modesame-domain · subdomains · all · regexsame-domainPertandingan mana saja yang termasuk dalam cakupan. regex cocok dengan include_patterns.
include_patternsstring[][]Pola regex yang harus dipenuhi oleh sebuah URL agar dapat dimasukkan ke dalam antrian (digunakan oleh regex mode / sebagai daftar putih).
exclude_patternsstring[][]Pola regex yang mengabaikan sebuah URL meskipun URL tersebut sebenarnya berada dalam cakupan.
max_depthint3Kedalaman tautan maksimum dari node awal (node awal berada pada kedalaman 0).
max_pagesint500Batas maksimum jumlah halaman yang dikunjungi sebelum proses perayapan selesai.
per_domain_rpsfloat1.0Laju pengisian ulang token-bucket per domain (permintaan per detik).
per_domain_concurrencyint1Jumlah maksimum permintaan selama penerbangan ke satu domain.
Cakupan Naive subdomains. Metode ini menggunakan dua label terakhir sebagai domain yang dapat didaftarkan, sehingga menghasilkan kecocokan berlebih pada host dalam Daftar Suffiks Publik seperti github.io atau co.uk. Gunakan same-domain atau regex untuk yang tersebut.

Hasil streaming (SSE)

Setiap tugas menampilkan aliran Server-Sent Events. Bacalah aliran tersebut untuk mengambil tindakan pada halaman-halaman begitu halaman-halaman tersebut terdeteksi, alih-alih menunggu proses perayapan selesai.

cURL
curl -N http://localhost:8001/api/v1/crawl/crawl_abc123/events

Aliran tersebut mengeluarkan lima jenis peristiwa:

PeristiwaKapan
statsRingkasan kemajuan berkala (telah dikunjungi / dalam antrian / gagal / dilewati deduplikasi / di luar cakupan / dicoba ulang).
pageSatu per URL yang dikunjungi. Menyimpan metadata lengkap ScrapeResponse dalam mode panen, metadata ringkas dalam mode penemuan.
page_errorSebuah URL yang gagal meskipun sudah dicoba berulang kali.
doneTerminal — proses perayapan selesai dengan lancar.
cancelledTerminal — proses perayapan dibatalkan.

Sebuah page Acara dalam mode penemuan terlihat seperti ini:

JSON
{
  "event": "page",
  "url": "https://example.com/docs/intro",
  "parent_url": "https://example.com/docs",
  "depth": 2,
  "status_code": 200,
  "took_ms": 812,
  "scrape_response": null
}

Status & hasil

Lebih suka metode polling? Catatan pekerjaan dapat diakses kapan saja — termasuk saat proses crawling sedang berlangsung, dengan halaman-halaman yang telah ditemukan sejauh ini. /results adalah alias dari titik akhir pekerjaan, yang dipertahankan untuk kesesuaian dengan scraper.

cURL
curl http://localhost:8001/api/v1/crawl/crawl_abc123
curl http://localhost:8001/api/v1/crawl/crawl_abc123/results
JSON
{
  "job_id": "crawl_abc123",
  "status": "running",
  "stats": {
    "visited": 47, "queued": 12, "failed": 0,
    "dedup_skipped": 9, "out_of_scope": 31, "retries_total": 2
  },
  "pages": [
    { "url": "https://example.com/", "parent_url": null,
      "depth": 0, "status_code": 200, "took_ms": 640 }
  ]
}
status melewati queuedrunningdone (atau failed / cancelled).

Membatalkan proses perayapan

Hentikan pekerjaan yang sedang berjalan dengan DELETE. Pembatalan lembut adalah pengaturan default dan pilihan yang aman.

cURL
# soft — stop scheduling, let in-flight requests drain
curl -X DELETE "http://localhost:8001/api/v1/crawl/crawl_abc123?hard=false"

# hard — abort in-flight asyncio tasks immediately
curl -X DELETE "http://localhost:8001/api/v1/crawl/crawl_abc123?hard=true"
Pembatalan paksa akan membuat scraper terputus. A ?hard=true akan membatalkan permintaan yang sedang diproses oleh crawler, tetapi scraper tidak memiliki cara untuk mengetahuinya — proses rendering halamannya tetap selesai di sisinya. Sebaiknya gunakan pembatalan lunak kecuali Anda benar-benar harus menghentikannya sekarang juga.

MCP

fastapi-mcp dipasang di /mcp sebagai titik akhir HTTP yang dapat dialirkan. Arahkan Claude atau Cursor ke sana dan alat-alat tersebut akan muncul secara otomatis:

  • health
  • create_crawl
  • get_crawl
  • get_crawl_results
  • cancel_crawl
~/.claude/settings.json
"open-crawler": {
  "type": "http",
  "url": "http://localhost:8001/mcp"
}
Endpoint SSE stream_crawl_events titik akhir SSE sengaja tidak dimasukkan ke dalam MCP — respons streaming tidak sesuai dengan alat berbasis permintaan/respons.

Panduan Konfigurasi

Permintaan — CrawlRequest

BidangTipeBawaanDeskripsi
seed_urlstring (URL)wajibURL tunggal yang menjadi titik awal proses perayapan.
scopeCrawlScopedefaultsBatas & kesopanan — lihat Ruang lingkup perayapan.
scrape_optionsScrapeOptionsdefaultsDiteruskan secara utuh ke scraper per halaman (url dimasukkan).
crawl_proxyScrapeOptions · nullnullProxy murah yang digunakan dalam mode penelusuran. Hanya proxy_type / proxy_pool_id / proxy_geo yang dibaca.
enable_scrapingboolfalseTetap pertahankan jumlah ScrapeResponse per halaman (true) atau hanya metadata penelusuran (false).

Per halaman — ScrapeOptions (terpilih)

BidangTipeBawaanDeskripsi
proxy_typenone · mobile · res_static · res_rotating · dc_static · …noneKumpulan proxy yang dilalui oleh rute pengambilan halaman.
devicedesktop · mobiledesktopViewport / Profil UA.
renderbooltrueRender menggunakan browser (diperlukan untuk tautan yang dibuat dengan JS).
stealthbooltrueTerapkan penguatan anti-deteksi.
wait_untildomcontentloaded · networkidledomcontentloadedKetika halaman tersebut dianggap sudah siap.
screenshotboolfalseAmbil tangkapan layar (mode panen).
extractExtractRule · nullnullAturan bidang CSS/XPath → terstruktur data per halaman.
session_idstring · nullnullGunakan kembali sesi scraper yang sudah terotentikasi — lihat Pengambilan data yang terotentikasi.

Variabel lingkungan

VariabelBawaanCatatan
SCRAPER_URLhttp://web-scraper:8000Scraper hulu (gunakan nama layanan Docker di dalam jaringan Compose).
WORKERS2Jumlah pekerjaan crawl paralel.
QUEUE_MAXSIZE200Kedalaman antrian pekerjaan yang tertunda.
JOB_TIMEOUT_MS3_600_000Batas waktu jam dinding untuk satu tugas perayapan.
SCRAPER_JOB_TIMEOUT_MS120_000Batas waktu permintaan scraper per halaman.
MAX_RETRIES3Jumlah upaya ulang per permintaan saat terjadi kegagalan sementara.
RETRY_HTTP_CODES[408,429,500,502,503,504]Kode status yang memicu upaya ulang.
RETRY_BACKOFF_MAX30.0Batas atas untuk backoff eksponensial (detik).
SESSION_MAX_ERROR_SCORE3.0Ambang batas penghentian sesi.
SESSION_MAX_USAGE50Putar sesi setelah digunakan sebanyak N kali.
SESSION_BLOCKED_CODES[401,403,429]Kode yang langsung mengakhiri sesi.

Referensi API

MetodeJalurTujuan
POST/api/v1/crawlBuat pekerjaan. Mengembalikan {"job_id":"…"}.
GET/api/v1/crawl/{id}Catatan pekerjaan — status, statistik, halaman yang sudah dikerjakan.
GET/api/v1/crawl/{id}/resultsAlias dari catatan pekerjaan.
GET/api/v1/crawl/{id}/eventsAlur SSE (stats/page/page_error/done/cancelled).
DELETE/api/v1/crawl/{id}?hard=boolBatalkan pekerjaan (pembatalan lunak atau keras).
GET/api/v1/healthKesehatan + jangkauan pengikis.

Rincian penting

Tanpa otentikasi (v1). Tidak ada titik akhir yang diotentikasi — fitur ini dirancang untuk jaringan internal atau jaringan tepercaya. Siapa pun yang dapat mengaksesnya dapat mengirimkan permintaan POST untuk proses perayapan dengan seed sembarang dan mengubahnya menjadi proxy SSRF. Pastikan fitur ini tetap berada di dalam VPC Anda atau di balik gateway otentikasi milik Anda sendiri.
robots.txt tidak dikonfirmasi. Crawler akan menjelajahi setiap URL yang termasuk dalam cakupan, terlepas dari /robots.txt. Anda bertanggung jawab untuk mematuhi aturan robot dan ketentuan situs pada target yang bukan milik Anda — gunakan exclude_patterns dan batasan laju agar tetap sopan.
Tidak ada penyimpanan permanen. Pekerjaan disimpan di memori dan akan direset saat kontainer dimulai ulang (sama halnya dengan scraper). Untuk memastikan ketahanan data, alirkan data SSE ke penyimpanan Anda sendiri (berupa berkas, Postgres, atau Kafka) seiring kedatangan halaman-halaman tersebut. Mulai ulang proses yang berjalan dalam jangka panjang secara berkala — pekerjaan yang telah selesai akan menumpuk di penyimpanan tersebut.
Pencarian yang terotentikasi. Buat sesi pada scraper (POST /sessions + POST /sessions/{id}/login), lalu kirimkan scrape_options.session_id. Scraper mengirim dan menerima cookie serta status penyimpanan pada setiap permintaan, sehingga setiap halaman yang dijelajahi akan melihat status yang telah diautentikasi.
Contoh langsung

Same-domain — default yang aman

Tetap di host seed yang persis, batasi kedalaman dan jumlah halaman, tetap sopan. Mode penemuan (enable_scraping: false) hanya menyimpan kerangka setiap halaman.


            

Disukai oleh tim data dan pengembang AI

Apa yang dikatakan oleh para pengembang yang menggunakan Yozh

5.0 / 5 · Ulasan 5
GitHub
Dalam satu sore, kami mengganti klaster Playwright internal kami dengan Yozh. Titik akhir MCP langsung terintegrasi ke dalam agen Claude kami — tanpa perlu kode penghubung sama sekali, crawler dan scraper langsung berfungsi dengan baik.
Marcus Reinhardt Insinyur Data Utama Northwind Analytics
X
Sistem preset ini adalah fitur andalannya. Kami memasukkan nama sumber dan mendapatkan respons JSON yang rapi; fitur pemulihan otomatisnya bahkan berhasil mendeteksi dua perubahan tata letak Amazon sebelum kami menyadarinya.
Priya Nair Pendiri ScrapeStack
Reddit
Akhirnya, ada scraper sumber terbuka yang memperlakukan proxy dan sesi sebagai fitur utama. Kami menjalankannya di balik sistem otentikasi untuk portal mitra — sesi tetap aktif dan hasilnya tetap konsisten di seluruh wilayah.
Daniel Osei Insinyur Backend Loopfeed
X
Setelah menghubungkannya ke Cursor melalui MCP, agen saya kini dapat mengambil data web secara langsung di tengah-tengah tugas. Proses pengambilan data streaming melalui SSE inilah yang selama ini menjadi hal yang kurang dalam alur kerja agen.
Elena Kovac Insinyur Kecerdasan Buatan Vektor Labs
GitHub
Kami beralih dari API pengambilan data berbayar untuk menghemat biaya dan bersiap menghadapi penurunan kualitas layanan — ternyata hasilnya justru sebaliknya. Sistem ini dihosting sendiri, tanpa tagihan per permintaan, dan skema outputnya lebih rapi daripada yang dulu kami bayar.
Sofia Almeida Manajer Teknik Tabbly
Sumber Terbuka · Lisensi MIT · 84 ★

Arahkan ke sebuah URL. Lihat situs tersebut dimuat

Yozh Crawler disertakan dalam repositori yang sama dengan scraper — satu docker compose up dan Anda sudah memiliki fitur pencarian + ekstraksi, yang siap digunakan dengan MCP, di infrastruktur Anda sendiri. Gratis. Selamanya. Berikan bintang kepada kami jika ini layak mendapat tempat di stack Anda.

Yozh Crawler + Scraper didistribusikan di bawah lisensi MIT. Silakan gunakan. Buat cabang (fork). Gunakan untuk mengembangkan aplikasi.