Auf einem Rechner hat cheerio in Node die Titel und hrefs aus einem synthetischen 10-MB-HTML-Dokument in 2.927,89 ms geparst und extrahiert. selectolax, ausgeführt über CPython mit einem C-gestützten Parser, erledigte dieselbe Extraktion der Felder in 158 ms. Die sortierten Titeltexte und href-Hashes stimmten überein. Das ist ein End-to-End-Vergleich des gesamten Stacks über Laufzeitumgebungen hinweg, kein isoliertes Urteil über den Parser-Algorithmus.
Bei einer 10-KB-Seite beträgt der Abstand 2×, und niemand würde es bemerken. Die eigentliche Frage ist, wo Ihre Seiten auf dieser Skala liegen.
Was cheerio ist
cheerio ist der HTML-Parser mit jQuery-Syntax für Node und aus gutem Grund die Standardantwort in diesem Ökosystem: 30.449 GitHub-Sterne, MIT-Lizenz und ein Push ins Repository am Tag vor meinem Test. Getestete Version: 1.2.0.
Offizielle Referenz: Die offizielle Einführung zu Cheerio.
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();
Wenn Sie jQuery geschrieben haben, kennen Sie die API bereits. Genau diese Vertrautheit ist einer der Hauptgründe, warum es sich in seinem Ökosystem durchgesetzt hat.
Unter der Haube steckt nicht ein einzelner Parser, sondern ein Stack: htmlparser2 und parse5 für das Parsen, domhandler und domutils für den Baum, cheerio-select für Selektoren sowie undici, encoding-sniffer und weitere — elf direkte Abhängigkeiten, die sich zu 22 Top-Level-Paketen und 9,0 MiB auf der Festplatte summieren. Diese Pakete liefern Parsing- und Encoding-Funktionen, tragen aber auch zum Dependency-Footprint bei. In diesem Test wurden fehlerhafte Eingaben geprüft, aber weder die Korrektheit der Kodierung noch einer der beiden Parser-Backends isoliert untersucht.
Die Messung und warum sie belastbar ist
Diese Forschungsbasis hatte bereits einen Parser-Benchmark: fünf Seitengrößen von 1 KB bis 10 MB, 50 Iterationen, drei unabhängige Durchläufe und — der entscheidende Teil — eine Paritätsprüfung, die den extrahierten Inhalt hasht, also sortierte Titel plus sortierte hrefs, gegen einen Referenzparser. Ein Parser, der stillschweigend Arbeit auslässt, kann keinen schnellen Wert posten.
cheerio dazuzunehmen erforderte zwei Prüfungen, bevor irgendeine Zahl zählt.
Lief die Referenz wieder dort, wo sie zuvor lag? selectolax wurde in derselben Sitzung auf denselben Fixtures erneut ausgeführt. Der Inhalts-Hash war auf 5 von 5 Größen reproduzierbar, und der p50 lag zwischen 0,989× und 1,079× des veröffentlichten Werts. Das ist also genau derselbe Rechner, der auch die ursprüngliche Tabelle erzeugt hat.
Hat cheerio dieselben bewerteten Felder erzeugt? Sein Inhalts-Hash — in Node mit derselben Regel berechnet, also SHA-256 über sortierte Titeltexte und sortierte hrefs — stimmte auf 5 von 5 Größen mit der Referenz überein. Das belegt Parität für diese sortierten Felder auf diesen Fixtures, nicht jedoch DOM-Struktur, Dokumentreihenfolge, Attribute, Textnormalisierung oder Fehlerkorrektur.
Erst dann bedeuten die Zeiten überhaupt etwas.
| Seitengröße | selectolax | lxml | PyQuery | cheerio (Node) | cheerio vs 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 in Millisekunden, Median aus drei Durchläufen. parser-bench.json. Die drei Python-Parser liefen in einem Prozess; cheerio lief in Node 22, also über eine Laufzeitgrenze hinweg und nicht nur auf Bibliotheksebene — siehe unten.
Die Tabelle ehrlich lesen

Die 1-KB-Zeile ist Rauschen. Über die drei Python-Parser hinweg lag die Streuung bei dieser Größe bei 77,6 %, und die Einzelmessungen überlappen stark — selectolax reichte von 0,0267 bis 0,0404 ms über seine drei Läufe. Bei 28 Mikrosekunden dominieren Timerauflösung und Scheduling. Ich würde bei 1 KB nichts ranken, auch cheerio nicht.
Der Mittelteil der Tabelle ist unspektakulär. 2× bis 4× bei Seiten zwischen 10 KB und 1 MB. Für einen Scraper mit ein paar Hundert Seiten sind das 45 Millisekunden pro Seite statt 15, und Sie werden es nie bemerken.
Die 10-MB-Zeile ist kein Rauschen. cheerios drei Läufe lagen bei 2.839, 2.928 und 2.954 ms — eng beieinander und klar von den anderen Zeilen getrennt. Das End-to-End-Ergebnis bei 10 MB weicht deutlich vom Muster der kleineren Größen ab. Fünf Größenpunkte reichen nicht aus, um asymptotische Komplexität zu belegen oder festzustellen, welche Runtime-, Parser-, Selektor-, Allocator- oder Garbage-Collection-Schicht den Sprung verursacht.
Es landet im Bereich von BeautifulSoup. Der veröffentlichte Benchmark hat auf demselben 10-MB-Fixture vier weitere Parser gemessen, und cheerios 2.927,89 ms daneben zu stellen ist der nützlichste Vergleich in diesem Artikel:
| Parser (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 |
Die vier Python-Zeilen sind die veröffentlichten Werte aus bench_parse.json; cheerios Wert stammt aus diesem Lauf. Der Referenzparser reproduzierte sich zwischen den beiden Läufen innerhalb von 0,989× bis 1,079×, daher sollten Unterschiede unter etwa 8 % als innerhalb dieser Unsicherheit betrachtet werden — cheerio gegen BeautifulSoups html.parser-Backend (5 % Abstand) liegt darin, cheerio gegen selectolax (18×) nicht.
BeautifulSoup ist die Bibliothek, zu der man greift, wenn Bequemlichkeit wichtiger ist und man bewusst akzeptiert, dass sie langsam ist — genau die Bibliothek, die in jedem Python-Performance-Thread als erstes ersetzt werden soll. Auf einem 10-MB-Dokument liegt cheerio am unteren Ende desselben Bereichs, nicht in dem Bereich der C-gestützten Parser, mit denen es oft zusammen genannt wird.
Die Frage nach einem Node-seitigen Ersatz bleibt in diesem Artikel offen. Neuere Node-Alternativen wurden nicht getestet, daher kann dieses Ergebnis weder sagen, dass ein Bibliothekswechsel unmöglich wäre, noch diese Alternativen als weniger etabliert abtun. Es zeigt nur den gemessenen cheerio-Pfad im Vergleich zu den aufgeführten Python-Stacks.
Das ist ebenso ein Laufzeit- wie ein Bibliotheksvergleich. cheerios Millisekunden entstehen durch Node-JIT und Garbage Collector; die anderen stammen von CPython, das C aufruft. Der Inhalts-Hash belegt, dass dieselbe Arbeit erledigt wurde, und beide Zahlen sind genau das, was Entwickler bei der Wahl eines Stacks tatsächlich erleben — aber niemand sollte daraus lesen, dass „cheerios Algorithmus 18× schlechter ist als der von selectolax“. So sah es auf diesem Rechner in der nativen Laufzeit jeder Bibliothek aus.
Die Realität des Setups
| Bibliothek | Pakete | Festplatte | Lizenz | Sterne | Letzter 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 |
Offizielle Referenz: Cheerio-Konfigurationsdokumentation.
metadata-snapshot.json, am Tag des Schreibens abgerufen.
npm install cheerio dauerte weniger als zwei Sekunden und zog 9,0 MiB nach. Der Kaltstart-Import wurde in einem separaten Konverterlauf auf demselben Rechner mit 0,056 s gemessen.
Elf direkte Abhängigkeiten sind für einen Parser ziemlich viel und sollten Ihnen auffallen, wenn Sie Ihren Baum auditieren: htmlparser2, parse5, parse5-htmlparser2-tree-adapter, parse5-parser-stream, domhandler, domutils, dom-serializer, cheerio-select, encoding-sniffer, undici und whatwg-mimetype. Zwei vollständige Parser-Implementierungen sind dort enthalten, weil cheerio je nach Anforderung beide verwenden kann.
Dreißigtausend Sterne und ein Push am Tag vor dem Test sind in dieser Kategorie so gesund wie ein Wartungssignal nur sein kann.
Speicher und was kaputter HTML damit macht
Speicherbedarf und Verhalten bei fehlerhaftem HTML beeinflussen Deployment und Fehlerbehandlung, deshalb werden beide hier getrennt gemessen.
Der breitere Stress-Test-Kontext ist im Vergleich von zehn Bibliotheken zu Speicher und fehlerhaftem HTML zu finden.
Peak Resident Memory per /usr/bin/time -l, jeweils ein frischer Prozess pro Zelle — die Import-Untergrenze ist das, was die Bibliothek im geladenen und inaktiven Zustand kostet, die Peaks enthalten das Dokument.
| Bibliothek | Runtime | Import-Untergrenze | 226 KB Peak | 10 MB Peak |
|---|---|---|---|---|
| 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- und Node-Baselines sind nicht direkt miteinander vergleichbar; der Interpreter steckt in beiden.
cheerio hat in dieser gemischten Kontexttabelle die höchste Import-Untergrenze mit 66,8 MiB, einschließlich Node-Runtime und Abhängigkeiten. Der Prozess erreichte beim 10-MB-Fixture 398,5 MiB. Die anderen Zeilen enthalten Parser, Konverter und Artikel-Extraktoren mit jeweils anderer Hauptaufgabe; nutzen Sie sie daher als Kontext für den Prozess-Footprint und nicht als direkte Peer-Performance-Rangliste. Die turndown-Zeile derselben Runtime lag deutlich höher, führt aber eine Konvertierung aus und nicht den hier für cheerio gemessenen Titel-und-href-Selektorvertrag.
Fehlerhaftes HTML. Zwölf Dokumente, bei denen jeweils genau eine Sache kaputt ist — nicht geschlossene Tags, falsch verschachtelte Inline-Elemente, nicht in Anführungszeichen gesetzte Attribute mit Leerzeichen, einsame schließende Tags, gar kein <html>, doppelte Attribute, ein mitten im Tag abgeschnittenes Dokument, kaputte Entities, ein offenes <script>, eine falsche Charset-Deklaration, ein Kommentar mit Markup und 600 Ebenen Verschachtelung — plus zwei wohlgeformte Kontrollen in passenden Größen, denn „es kam nichts zurück“ sagt nur dann etwas über Fehlerhaftigkeit, wenn die Bibliothek bei einem sauberen Dokument derselben Größe nicht ebenfalls still bleibt.
cheerio löste auf 0 von 14 Fällen eine Ausnahme aus und gab auf 0 nichts zurück; es stellte auf den fehlerhaften Fixtures 11/22 bewertete Marker wieder her (malformed-results.json). Bei Parsern prüft der Scorer Heading- und Link-Sentinels über elf bewertbare fehlerhafte Dokumente hinweg; der Absatz-Sentinel wird nicht bewertet, und das ungeschlossene-<script>-Fixture ist ausgeschlossen. Ohne Baseline mit demselben Vertrag ist 11/22 keine Qualitätsrangfolge. Die belastbare Schlussfolgerung ist, dass cheerio auf allen vierzehn fehlerhaften-plus-Kontroll-Eingaben nicht leer zurückkam und keine Exception auslöste, dabei aber nur die Hälfte der bewerteten Marker wiederherstellte.
Vor- und Nachteile
Vorteile. Vertraute jQuery-Syntax. MIT. Ein Wartungssignal mit Zeitstempel: 30.449 Sterne und Repository-Aktivität am Tag vor dem Test. Zwei Parser-Backends und encodingbezogene Pakete sind vorhanden, auch wenn Backend-Recovery und Encoding-Genauigkeit hier nicht isoliert geprüft wurden. Der sortierte Titel-plus-href-Hash stimmte auf jeder getesteten Größe mit der Referenz überein.
Nachteile. 18,5× langsamer als selectolax auf einem 10-MB-Dokument und 4× auf 1 MB. Elf direkte Abhängigkeiten, darunter zwei vollständige Parser-Implementierungen. Nur Node. Und in der Dokumentation gibt es keinen Hinweis darauf, ab welcher Größe es nicht mehr die offensichtliche Wahl ist.
Wer es nutzen sollte und wer nicht
cheerio nutzen sollten Sie, wenn Sie in Node arbeiten, die jQuery-ähnliche API wertvoll ist und Ihre repräsentativen Seiten ungefähr den getesteten Größen bis 1 MB entsprechen. Ein Megabyte ist der größte getestete Punkt vor dem deutlichen Sprung bei 10 MB; dieser Artikel bestimmt nicht die Schwelle dazwischen und behauptet auch nicht, wie viel des Webs darunter fällt.
Vorher benchmarken sollten Sie es bei sehr großen HTML-Dokumenten wie generierten Reports, Katalog-Dumps oder langen Listen-Seiten. XML-Sitemap-Verhalten wurde nicht getestet. Beim 10-MB-HTML-Fixture sind 2,9 Sekunden pro Dokument ein spürbarer Kostenfaktor, der sich summiert.
Wenn Sie in Python sind, sagt dieser Vergleich etwas anderes: selectolax, lxml und PyQuery liegen ab 10 KB faktisch gleichauf (innerhalb von 0,5 % bis 5,4 %, mit überlappenden Laufbereichen), daher sollten Sie nach API und nicht nach Geschwindigkeit entscheiden. Der interessante Wert ist der Abstand von cheerio zu allen dreien, nicht der Unterschied zwischen ihnen.
Wo eine verwaltete API hineinpasst
cheerio parst HTML, das Sie bereits haben. Es lädt keine Seiten, rendert kein JavaScript und kümmert sich nicht um Anti-Bot-Schichten — und gerade das ist bei vielen realen Zielen die schwierigere Hälfte der Aufgabe.
Ein verwalteter Fetch-/Render-/Extraktionsdienst, einschließlich unseres eigenen Thunderbit, sitzt an einer anderen Verantwortungsgrenze. Thunderbit wurde hier nicht benchmarked. Der relevante Unterschied ist: geliefertes HTML mit Selektoren parsen versus Beschaffung, Rendering und Extraktion auslagern. Dieser Artikel liefert keinen fairen Vergleich auf derselben Metrik für Qualität, Latenz oder Kosten.
Die faire Einordnung lautet: Wenn Sie das HTML haben und Ihre Selektoren kennen, ist cheerio kostenlos und angenehm zu verwenden. Wenn Sie Seiten in großem Umfang abrufen oder lieber die Daten als das DOM beschreiben möchten, ist das ein anderer Kauf.
Für das breitere Feld behandelt unser Überblick über Web-Scraping-APIs gehostete Optionen und der Pillar zu Open-Source-Scrapern die selbst gehosteten. Wenn die extrahierten Daten in ein Modell gehen sollen, zeigt HTML in Python zu Markdown konvertieren, wo Fidelity verloren geht.
Thunderbit für Web-Datenextraktion testen
Sollten Sie cheerio verwenden?
Ja, in Node, wenn die passende API wichtig ist und Ihre repräsentativen Dokumente in der getesteten Spanne von klein bis 1 MB bleiben.
Die Vertrautheit der API und die aktuellen Wartungssignale sind legitime Auswahlkriterien. Der Benchmark beweist nicht, dass es eine bestimmte Support-Antwort gibt oder dass die getestete Verteilung der Seitengrößen Ihrem Produktionsbestand entspricht.
Merken Sie sich vor allem die 10-MB-Zahl. Irgendwo zwischen 1 MB und 10 MB hört cheerios Kostenverhalten auf, den anderen zu folgen, und beginnt sich zu vervielfachen — 4× wird zu 18,5×. Wenn Ihr Korpus so große Dokumente enthält, benchmarken Sie vor der Entscheidung, denn die Bibliothek warnt Sie nicht davor.
Thunderbit für Web-Datenextraktion testen Get Started Free
FAQs
Ist der Vergleich von cheerio mit Python-Parsern fair? Es ist ein Stack-Vergleich, kein Algorithmus-Vergleich. Alle vier erzeugten unter der Hash-Regel auf 5 von 5 Seitengrößen identische sortierte Titeltexte und hrefs. Das beweist nicht, dass die Parser insgesamt gleichwertig sind. cheerios Zeiten enthalten das Laufzeitverhalten von Node, die anderen enthalten CPython-Aufrufe an C-gestützte Parser; der Vergleich beschreibt diese End-to-End-Entscheidungen.
Warum wird die 1-KB-Zeile nicht gerankt? Weil bei 28 Mikrosekunden die Messung vom Rauschen dominiert wird. Über drei Durchläufe hinweg lag die Streuung der Python-Parser bei 77,6 %, und die Einzelmessungen überlappten sich. Jede Ordnung in dieser Größenordnung wäre ein Artefakt. Ab 10 KB ist die Zeile stabil genug zum Lesen.
Was verursacht den Sprung bei 10 MB? Dieser Test sagt es nicht. Er zeigt nur, dass der Sprung real und kein Rauschen ist: cheerios drei Läufe lagen bei 2.839, 2.928 und 2.954 ms und damit klar getrennt vom Rest, während der Abstand bei 1 MB 4× betrug. Die Ursache zu isolieren würde bedeuten, die Parser-Backends von cheerio separat zu profilieren; das lag hier außerhalb des Umfangs.
Wie viele Abhängigkeiten hat es wirklich?
Elf direkte, 22 Top-Level nach Auflösung, 9,0 MiB auf der Festplatte. Zwei davon sind vollständige Parser-Implementierungen — htmlparser2 und parse5 — weil cheerio je nach Bedarf beide nutzen kann. Das ist der Preis dafür, sowohl tolerantes als auch standardskonformes Parsing zu unterstützen, und wichtig, wenn Sie Abhängigkeitsbäume prüfen.
Was wurde hier nicht getestet?
Der aktuelle Entwurf testete tatsächlich den Peak-Prozessspeicher mit einem 226-KB- und einem 10-MB-Dokument sowie ein Set aus 14 fehlerhaften Eingaben plus Kontrollen, bei dem cheerio auf keinem Fall eine Exception auslöste, auf allen nicht leer zurückgab und 11/22 bewertete Marker wiederherstellte. Nicht getestet wurden Streaming über parse5-parser-stream, Encoding-Korrektheit, backend-spezifische Fehlerkorrektur, die genaue Position des Performance-Sprungs zwischen 1 und 10 MB, XML-Parsing oder neuere Node-Alternativen. Die rohen relativen Artifact-Links benötigen außerdem zum Veröffentlichungszeitpunkt dieselbe öffentliche Verzeichnisstruktur; andernfalls brauchen sie dauerhafte öffentliche URLs oder einen Repository-Commit-Verweis.


