Tek bir makinede, Node üzerindeki cheerio, 10 MB’lık sentetik bir HTML belgesinden başlıkları ve href’leri ayrıştırıp çıkarmayı 2.927,89 ms içinde tamamladı. CPython üzerinden, C destekli bir ayrıştırıcıyla çalışan selectolax ise aynı alanları 158 ms içinde çıkardı. Sıralanmış başlık metinleri ve href karmaları birebir eşleşti. Bu, yalnızca ayrıştırıcı algoritmasını değil, çalışma zamanlarını da kapsayan uçtan uca bir yığın karşılaştırmasıdır.
10 KB’lık bir sayfada fark 2 kattır; kimse bunu fark etmez. Asıl soru, senin sayfalarının bu eğrinin neresinde olduğudur.
cheerio nedir?
cheerio, Node için jQuery sözdizimine sahip HTML ayrıştırıcısıdır ve bu ekosistemde boşuna varsayılan cevap değildir: 30.449 GitHub yıldızı, MIT lisansı ve ben bu testi çalıştırmadan bir gün önce repoya yapılan bir push. Test edilen sürüm: 1.2.0.
Resmî kaynak: Cheerio'nun resmî tanıtımı.
import * as cheerio from "cheerio";
const $ = cheerio.load(html);
const titles = $("h3.title").map((_, e) => $(e).text()).get();
const hrefs = $("a").map((_, e) => $(e).attr("href")).get();
jQuery kullandıysan, bu arayüzü zaten biliyorsundur. Ekosistemini kazanmasının en büyük nedeni de bu aşinalık.
İçeride tek bir ayrıştırıcı yok, bir yığın var: ayrıştırma için htmlparser2 ve parse5, ağaç yapısı için domhandler ve domutils, seçiciler için cheerio-select, ayrıca undici, encoding-sniffer ve diğerleri — 11 doğrudan bağımlılık, toplamda 22 üst düzey pakete ve diskte 9,0 MiB’a ulaşıyor. Bu paketler ayrıştırma ve kodlama yetenekleri sağlar; aynı zamanda bağımlılık yükünü de artırır. Bu inceleme bozuk girdi çıktısını test etti, ancak kodlama doğruluğunu test etmedi ya da iki ayrıştırıcı arka ucundan hiçbirini ayrı değerlendirmedi.
Ölçüm ve neden güvenilir olduğu
Bu çalışma setinde zaten bir ayrıştırıcı benchmark’ı vardı: 1 KB ile 10 MB arasında beş sayfa boyutu, 50 iterasyon, üç bağımsız koşu ve en önemlisi — çıkarılan içeriği, sıralanmış başlıkları ve sıralanmış href’leri bir referans ayrıştırıcıyla karşılaştıran bir eşdeğerlik kapısı. Sessizce işi atlayan bir ayrıştırıcı hızlı görünemez.
cheerio’yu buna eklemek, herhangi bir sayım geçerli olmadan önce iki kontrol gerektirdi.
Referans daha önce olduğu yere yine ulaştı mı? selectolax aynı oturumda, aynı örnek dosyalarla yeniden çalıştırıldı. İçerik karması 5/5 boyutta tekrarlandı ve p50 değeri yayımlanan rakamın 0,989× ile 1,079× arasında kaldı. Yani bu, orijinal tabloyu üreten makinedir.
cheerio aynı skorlanan alanları üretti mi? Onun içerik karması — Node içinde, aynı kuralla, sıralanmış başlık metni ve sıralanmış href’ler üzerinde SHA-256 hesaplanarak — 5/5 boyutta referansla eşleşti. Bu, bu örneklerde o sıralı alanlar için eşdeğerliği kanıtlar; DOM şekli, belge sırası, öznitelikler, metin normalizasyonu veya hata toparlama için değil.
Ancak o zaman süreler anlam taşır.
| Sayfa boyutu | selectolax | lxml | PyQuery | cheerio (Node) | cheerio / selectolax |
|---|---|---|---|---|---|
| 1 KB | 0,0286 ms | 0,0508 | 0,0456 | 0,1147 ms | 4,0× |
| 10 KB | 0,1725 ms | 0,1802 | 0,1728 | 0,3490 ms | 2,0× |
| 100 KB | 1,4855 ms | 1,4145 | 1,4093 | 3,8399 ms | 2,6× |
| 1 MB | 14,97 ms | 15,03 | 14,96 | 59,37 ms | 4,0× |
| 10 MB | 158,10 ms | 165,25 | 162,86 | 2.927,89 ms | 18,5× |
p50 milisaniye, üç koşunun ortancası. parser-bench.json. Üç Python ayrıştırıcısı tek bir süreçte çalıştı; cheerio ise Node 22’de çalıştı, yani bu hem bir çalışma zamanı hem de bir kütüphane sınırıdır — aşağıya bakın.
O tabloyu dürüstçe okumak

1 KB satırı gürültüdür. Üç Python ayrıştırıcısı arasında o boyuttaki fark %77,6’dır ve tek tek koşular ciddi biçimde üst üste biner — selectolax, üç koşusunda 0,0267 ile 0,0404 ms arasında değişti. 28 mikrosaniyede zamanlayıcı çözünürlüğü ve planlama etkisi baskın hale gelir. 1 KB’de hiçbir şeyi sıralamam; cheerio dahil.
Tablonun ortası çok da dikkat çekici değil. 10 KB ile 1 MB arasındaki sayfalarda 2× ila 4× fark var. Birkaç yüz sayfa işleyen bir scraper için bu, sayfa başına 45 ms yerine 15 ms demektir ve bunu asla hissetmezsin.
10 MB satırı gürültü değil. cheerio’nun üç koşusu 2.839, 2.928 ve 2.954 ms geldi — birbirine yakın ama diğer satırlardan net biçimde ayrışıyor. 10 MB’lık uçtan uca sonuç, küçük boyutlu düzenekten keskin şekilde sapıyor. Beş veri noktası, asimptotik karmaşıklığı kanıtlamaz ve sıçramaya hangi çalışma zamanı, ayrıştırıcı, seçici, bellek tahsisi veya çöp toplama katmanının yol açtığını söylemez.
BeautifulSoup bandına düşüyor. Yayımlanan benchmark aynı 10 MB örneğinde dört ayrıştırıcıyı daha ölçmüştü; cheerio’nun 2.927,89 ms sonucunu onların yanına koymak bu yazıdaki en faydalı şey:
| Ayrıştırıcı (10 MB) | p50 |
|---|---|
| selectolax (lexbor) | 159,93 ms |
| lxml | 172,93 ms |
| parsel | 231,85 ms |
| selectolax (modest) | 247,95 ms |
| BeautifulSoup + lxml | 2.261,56 ms |
| BeautifulSoup + html.parser | 2.788,75 ms |
| cheerio | 2.927,89 ms |
Dört Python satırı, bench_parse.json içindeki yayımlanmış değerlerdir; cheerio’nunki bu çalışmadan geliyor. Referans ayrıştırıcı iki koşu arasında 0,989×–1,079× aralığında tekrarlandı; bu yüzden yaklaşık %8’den küçük farkları belirsizlik sınırları içinde kabul edin — cheerio ile BeautifulSoup’un html.parser arka ucu arasındaki fark (%5) bunun içindedir, cheerio ile selectolax arasındaki fark (18×) değildir.
BeautifulSoup, insanların rahatlık için seçip yavaş olduğunu bilerek kullandığı kütüphanedir — Python performans tartışmalarında herkesin “bunun yerine şunu kullan” dediği çözümdür. 10 MB’lık bir belgede cheerio da aynı bandın en altına düşüyor; C destekli ayrıştırıcıların bandına değil.
Node tarafında değişim sorusu bu yazıda açık kalıyor. Daha yeni Node alternatifleri test edilmedi; bu nedenle sonuç, kütüphane değiştirmeyi imkânsız göstermez ya da onları daha az yerleşik diye küçümsemez. Yalnızca ölçülen cheerio yolunu listelenen Python yığınlarıyla karşılaştırır.
Bu aynı zamanda bir çalışma zamanı karşılaştırmasıdır, sadece kütüphane değil. cheerio’nun milisaniyeleri Node’un JIT’i ve çöp toplayıcısından gelir; diğerleri ise CPython’un C destekli ayrıştırıcılara çağrı yapmasından. İçerik karması aynı işin yapıldığını kanıtlar ve iki sayı da bir geliştiricinin gerçekten deneyimlediği şeydir — ama kimse bunu “cheerio’nun algoritması selectolax’tan 18× daha kötü” diye okumamalı. Bu, bu makinede, her kütüphanenin kendi yerel çalışma zamanında olan şeydir.
Kurulum gerçeği
| Kütüphane | Paketler | Disk | Lisans | Yıldız | Son push |
|---|---|---|---|---|---|
| cheerio | 22 (npm) | 9,0 MiB | MIT | 30.449 | 2026-08-11 |
| PyQuery | 3 (pip) | 20,1 MiB | BSD | 2.380 | 2026-07-27 |
Resmî kaynak: Cheerio yapılandırma dokümantasyonu.
metadata-snapshot.json, yazının yazıldığı gün çekildi.
npm install cheerio iki saniyenin altında sürdü ve 9,0 MiB indirdi. Soğuk import, aynı makinede ayrı bir dönüştürme çalışmasında 0,056 s olarak ölçüldü.
On bir doğrudan bağımlılık bir ayrıştırıcı için fazlaca sayılır; ağacını denetliyorsan bilmeye değerdir: htmlparser2, parse5, parse5-htmlparser2-tree-adapter, parse5-parser-stream, domhandler, domutils, dom-serializer, cheerio-select, encoding-sniffer, undici ve whatwg-mimetype. İki tam ayrıştırıcı uygulaması birlikte geliyor, çünkü cheerio ona ne istediğine bağlı olarak ikisini de kullanabiliyor.
Otuz bin yıldız ve testten bir gün önce yapılan push, bu kategoride bakım sinyali olarak oldukça sağlıklı.
Bellek ve bozuk HTML’nin etkisi
Bellek ayak izi ve bozuk girdi davranışı dağıtım ve hata yönetimini etkiler; bu yüzden ikisi burada ayrı ölçülüyor.
Daha geniş stres testi bağlamı için on kütüphaneli bellek ve bozuk HTML karşılaştırmasına bakın.
Tepe çalışan bellek /usr/bin/time -l ile, hücre başına yeni bir süreç kullanılarak ölçüldü — import tabanı kütüphanenin yüklenmiş ve boş durumdaki maliyetidir; tepeler belgenin maliyetini de içerir.
| Kütüphane | Çalışma zamanı | Import tabanı | 226 KB tepe | 10 MB tepe |
|---|---|---|---|---|
| html2text | python3.14 | 18,7 | 19,9 | 71,2 |
| pyquery | python3.14 | 30,3 | 33,9 | 172,5 |
| resiliparse | python3.14 | 20,5 | 25,1 | 225,1 |
| markdownify | python3.14 | 23,9 | 28,9 | 278,5 |
| goose3 | python3.14 | 44,1 | 52,4 | 398,5 |
| cheerio | node22 | 66,8 | 76,5 | 398,5 |
| justext | python3.14 | 30,3 | 36,6 | 431,2 |
| newspaper4k | python3.14 | 52,6 | 61,8 | 668,5 |
| trafilatura | python3.14 | 52,5 | 64,8 | 927,1 |
| turndown | node22 | 47,8 | 68,4 | 2947,1 |
memory-results.json. Python ve Node taban çizgileri birbirleriyle doğrudan karşılaştırılamaz; her ikisinin içinde de yorumlayıcı vardır.
cheerio, bu karışık bağlam tablosunda 66,8 MiB ile en yüksek import tabanına sahip; buna Node çalışma zamanı ve bağımlılıklar dahil. Süreci 10 MB örneğinde 398,5 MiB’ye kadar çıktı. Diğer satırlar, farklı ana işler yapan ayrıştırıcıları, dönüştürücüleri ve makale çıkarıcıları içeriyor; bu yüzden onları eşler arası performans sıralaması değil, süreç ayak izi bağlamı olarak kullan. Aynı çalışma zamanındaki turndown satırı çok daha yüksek bir tepe gördü, ancak cheerio için ölçülen başlık-ve-href seçim sözleşmesi yerine dönüştürme yapıyor.
Bozuk HTML. Tam olarak bir şeyin bozulduğu on iki belge — kapatılmamış etiketler, yanlış iç içe geçmiş satır içi öğeler, boşluk içeren tırnaksız öznitelikler, fazladan kapanış etiketleri, hiç <html> olmaması, yinelenen öznitelikler, ortadan kesilmiş bir etiket, hatalı entity’ler, kapatılmamış bir <script>, yanlış charset bildirimi, markup içeren bir yorum ve 600 seviye iç içe yapı — artı iki düzgün biçimli kontrol belgesi, çünkü “hiçbir şey döndürmedi” ifadesi, aynı boyutta temiz bir belgede de sessiz kalan bir kütüphane varsa bozukluk hakkında anlamlı olmaz.
cheerio, 14 dosyanın 0’ında hata fırlattı ve 0’ında boş döndü; bozuk örneklerde 22 skorlanabilir işaretin 11’ini kurtardı (malformed-results.json). Ayrıştırıcılar için skorlayıcı, skorlanabilir on bir bozuk belgede başlık ve bağlantı işaretlerini kontrol eder; paragraf işaretini skorlamaz ve kapatılmamış <script> örneğini dışarıda bırakır. Bu bölümde aynı sözleşmeye sahip bir temel olmadığından, 11/22 bir kalite sıralaması değildir. Desteklenen sonuç, cheerio’nun on dört bozuk+kontrol girdisinin hepsinde hata vermeden boş olmayan çıktı döndürdüğü ve skorlanan işaretlerin yarısını kurtardığıdır.
Artıları ve eksileri
Artıları. Tanıdık jQuery sözdizimi. MIT lisansı. 30.449 yıldız ve testten bir gün önceki depo etkinliğiyle zaman damgalı bir bakım sinyali. İki ayrıştırıcı arka ucu ve kodlama ile ilgili paketler mevcut, ancak burada arka uç toparlaması ve kodlama doğruluğu ayrı ölçülmedi. Sıralanmış başlık+href karması her örnek boyutunda referansla eşleşti.
Eksileri. 10 MB’lık belgede selectolax’tan 18,5×, 1 MB’da ise 4× daha yavaş. On bir doğrudan bağımlılık, bunların içinde iki tam ayrıştırıcı uygulaması. Sadece Node. Ve dokümantasyonunda, artık açık tercih olmaktan çıktığı bir boyutu işaret eden hiçbir şey yok.
Kim kullanmalı, kim kullanmamalı?
cheerio kullan eğer Node içindeysen, jQuery benzeri API senin için değerliyse ve örnek belgeler test edilen 1 MB’a kadar olan boyutlara benziyorsa. 1 MB, keskin 10 MB sıçramasından önce test edilen en büyük noktadır; bu yazı ikisi arasındaki eşik değerini belirlemez ve web’in ne kadarının bunun altında kaldığını iddia etmez.
Kullanmadan önce benchmark yap eğer üretilmiş raporlar, katalog dökümleri veya uzun liste sayfaları gibi çok büyük HTML belgeleriyle çalışıyorsan. XML sitemap davranışı test edilmedi. 10 MB HTML örneğinde belge başına 2,9 saniye, biriktiğinde hissedilir bir maliyettir.
Python tarafındaysan, bu karşılaştırma başka bir şey söylüyor: selectolax, lxml ve PyQuery 10 KB’dan itibaren pratikte başa baş gidiyor (%0,5 ila %5,4 aralığında, koşu aralıkları da üst üste biniyor); bu yüzden hıza göre değil API’ye göre seç. cheerio’nun bu üçüne karşı farkı asıl ilginç sayı; onların kendi aralarındaki fark değil.
Yönetilen bir API nereye oturur?
cheerio, zaten elinde olan HTML’i ayrıştırır. Sayfayı getirmez, JavaScript çalıştırmaz, anti-bot katmanını yönetmez — ve gerçek hedeflerin çoğunda işin daha zor yarısı da budur.
Bizim kendi Thunderbit çözümümüz de dahil olmak üzere yönetilen bir getirme/oluşturma/çıkarma servisi, farklı bir sorumluluk sınırında yer alır. Thunderbit burada benchmark edilmedi. Buradaki önemli ayrım, sağlanan HTML’i seçicilerle ayrıştırmak ile veri toplama, render etme ve çıkarmayı dışarıya vermek arasındadır; bu makale aynı metriklerle kalite, gecikme veya maliyet karşılaştırması sunmaz.
Adil çerçeve şu: HTML sende varsa ve seçicilerini biliyorsan, cheerio ücretsiz ve kullanımı keyiflidir. Sayfaları ölçekli biçimde çekiyorsan veya DOM’u değil veriyi tarif etmeyi tercih ediyorsan, bu başka bir satın alımdır.
Daha geniş alan için web scraping API derlememiz barındırılan seçenekleri, açık kaynak scraper rehberimiz ise kendi barındırdıklarını kapsar. Çıkarılan çıktı bir modele gidecekse, Python’da HTML’yi Markdown’a dönüştürme konusunda doğruluk kaybının nerede başladığını anlatıyoruz.
Web Verisi Çıkarmak için Thunderbit’i Deneyin
cheerio kullanmalı mısın?
Evet, Node içinde, API uyumu önemliyse ve örnek belgeler test edilen küçükten 1 MB’a kadar olan aralıkta kalıyorsa.
API aşinalığı ve güncel bakım sinyalleri, seçime dahil edilmesi gereken gerçek kriterlerdir. Benchmark, belirli bir destek yanıtının var olduğunu ya da test edilen sayfa boyutu dağılımının üretim veri kümenizle eşleştiğini kanıtlamaz.
Akılda tutulacak sayı 10 MB olanıdır. 1 MB ile 10 MB arasında bir yerde cheerio’nun maliyeti diğerlerini takip etmeyi bırakıp katlanmaya başlıyor — 4×, 18,5× oluyor. Eğer veri kümen bu kadar büyük belgeler içeriyorsa, karar vermeden önce benchmark yap; çünkü kütüphane sana bunu söylemez.
Web Verisi Çıkarmak için Thunderbit’i Deneyin Get Started Free
SSS
cheerio’yu Python ayrıştırıcılarına karşı kıyaslamak adil mi? Bu bir algoritma karşılaştırması değil, yığın karşılaştırmasıdır. Dördü de 5/5 sayfa boyutunda, hash kuralı altında sıralanmış başlık metinlerini ve href’leri birebir aynı üretti. Bu, toplam ayrıştırıcı eşdeğerliğini kanıtlamaz. cheerio’nun süreleri Node çalışma zamanı davranışını da içerir; diğerleri ise CPython’un C destekli ayrıştırıcılara çağrı yapmasını içerir. Karşılaştırma bu uçtan uca seçimleri anlatır.
1 KB satırı neden sıralanmıyor? Çünkü 28 mikrosaniyede ölçüm gürültü tarafından domine edilir. Üç koşu boyunca Python ayrıştırıcıları %77,6’lık bir aralık gösterdi ve tek tek koşular birbirinin üzerine bindi. O boyutta verilecek herhangi bir sıralama yapay olurdu. 10 KB ve üzeri okumak için yeterince kararlıdır.
10 MB’daki sıçramaya ne sebep oluyor? Bu test bunu söylemiyor. Ortaya koyduğu şey, sıçramanın gerçek olduğu ve gürültü olmadığıdır: cheerio’nun üç koşusu 2.839, 2.928 ve 2.954 ms geldi; diğerlerinin hepsinden belirgin biçimde ayrıştı, 1 MB’daki fark ise 4 kattı. Nedeni ayırmak için cheerio’nun ayrıştırıcı arka uçlarını ayrı ayrı profillemek gerekirdi; bu çalışmanın kapsamı dışında kaldı.
Gerçekte kaç bağımlılığı var?
11 doğrudan, çözümleme sonrası 22 üst düzey, diskte 9,0 MiB. Bunların ikisi — htmlparser2 ve parse5 — tam ayrıştırıcı uygulamalarıdır; çünkü cheerio ikisini de kullanabilir. Bu, hem affedici hem de standartlara uygun ayrıştırmayı birlikte ele almanın bedelidir ve bağımlılık ağaçlarını denetliyorsan bilmeye değerdir.
Burada neler test edilmedi?
Testler, bir 226 KB ve bir 10 MB belge üzerinde süreç tepe belleğini; ayrıca cheerio’nun hiçbirinde hata vermediği, hepsinde boş olmayan çıktı döndürdüğü ve 22 skorlanabilir işaretin 11’ini kurtardığı 14 girdilik bozuk+kontrol setini kapsadı. parse5-parser-stream üzerinden akış işlemi, kodlama doğruluğu, arka uçlara özgü toparlama, 1 ile 10 MB arasındaki performans sıçramasının yeri, XML ayrıştırma veya daha yeni Node alternatifleri kapsanmadı.


