Was Crawlee so praktisch macht, ist die Crawl-Orchestrierung, die sowohl HTTP-Parsing als auch Browser-Ausführung unterstützt. Dieselbe URL kann je nach gewähltem Crawler und Bereitschaftsbedingung also ganz unterschiedliche Ergebnisse liefern.
Auf der öffentlichen Quotes-to-Scrape-JS-Seite fand CheerioCrawler nach 0 Ziel-Zitate und PlaywrightCrawler nach dem Warten auf .quote 10. Der Crawl-Ablauf ist ähnlich, aber das war kein einfacher Tausch nur der Klasse mit einer einzigen Zeile: Der Cheerio-Handler nutzte $, während der Playwright-Handler page, ein explizites Warten und eine Extraktion direkt im Browser verwendete.
Was Crawlee eigentlich ist
Crawlee (das Projekt apify/crawlee, Version 3.17.0) ist eine Web-Scraping- und Browser-Automatisierungsbibliothek fĂĽr Node.js und TypeScript. Sie unterstĂĽtzt HTTP-Crawling auf Basis von Cheerio oder JSDOM sowie Browser-Crawling mit Playwright oder Puppeteer. Das Projekt steht unter Apache-2.0; prĂĽfen Sie die Hinweise und Pflichten zur Namensnennung fĂĽr Ihre Verteilung.
Das wichtige Denkmodell ist, „Seite abrufen“ und „Seite auslesen“ zu trennen. Der eine Weg lädt rohes HTML herunter und führt kein JavaScript aus. Der andere startet Chromium und kann die Skripte der Seite ausführen, braucht aber trotzdem eine passende Bereitschaftsbedingung und kann Inhalte verpassen, die an Interaktion gebunden, lazy geladen, in Shadow DOM versteckt, durch API-Fehler blockiert oder durch Bot-Schutz abgeschirmt sind. Crawlee stellt entlang dieser beiden Wege passende Lebenszyklus-Konzepte bereit, keine austauschbaren DOM-Primitiven.
Genau das sollte man verstanden haben, bevor man auch nur einen Selektor schreibt, denn die Wahl zwischen diesen beiden Engines entscheidet darüber, ob Ihr Scraper auf einer bestimmten Website Daten zurückliefert oder ins Leere läuft.
Zentrale Funktionen: zwei Engines, eine API-Oberfläche

CheerioCrawler lädt HTML und parst es mit Cheerio; PlaywrightCrawler steuert Chromium und kann Screenshots erstellen. Beide verwenden einen requestHandler, bieten run() an und teilen sich Crawl-Konzepte wie Queues und Link-Erkennung. Die Handler-Kontexte unterscheiden sich jedoch: Der getestete Cheerio-Pfad extrahierte über $, während der Browser-Pfad page, waitForSelector und $$eval nutzte. Queue- und Lifecycle-Logik können vertraut bleiben, aber die Extraktionslogik braucht möglicherweise einen Adapter oder muss neu geschrieben werden.
Darunter liefert Crawlee die Infrastruktur, die ein echter Crawl braucht. Eine RequestQueue verwaltet die Frontier der zu besuchenden URLs, dedupliziert sie und verfolgt den Bearbeitungsstand. enqueueLinks entdeckt und reiht neue URLs ein (mit Selektor- und Same-Host-Filterung), damit ein Crawl selbstständig ausufern kann. Ein Dataset sammelt Ihre gescrapten Datensätze für den Export. Standardmäßig speichert Crawlee all das lokal im Verzeichnis storage/ auf der Festplatte — praktisch für das Fortsetzen, und leicht nervig, wenn man zum ersten Mal einen storage/-Ordner im Projekt findet, den man gar nicht angefordert hat (mein Test-Setup leitete das in ein Temp-Verzeichnis um und deaktivierte die Persistenz, um den Test sauber zu halten).
Die einzelnen Bausteine sind für sich genommen unspektakulär. Der Punkt ist, dass sie in beiden Engines gemeinsam genutzt werden, sodass Queue, Link-Erkennung und Dataset sich gleich verhalten, egal ob Sie per HTTP oder im Browser crawlen. Man lernt eine API und bekommt zwei Abrufstrategien.
Setup: der Browser muss separat installiert werden
Die getestete Installation enthielt nach der Paketinstallation keine Chromium-Executable.

npm install crawlee playwright lief bei mir sauber durch — 85 Pakete, 0 Schwachstellen, kein Drama. Wenn man dort aufhört und einen CheerioCrawler startet, funktioniert alles, weil HTTP-Crawling keinen Browser braucht.
In dieser Umgebung musste Chromium separat mit npx playwright install chromium installiert werden; ohne diesen Schritt konnte PlaywrightCrawler nicht starten. Die beobachtete Browser-Nutzlast lag ungefähr bei 82 MiB, allerdings geht aus den ursprünglichen Notizen nicht hervor, ob es sich dabei um Transfer- oder Festplattengröße handelt. Das ist eine setupspezifische Beobachtung, keine feste Produkteigenschaft. Dokumentationspfade und Paketverhalten können sich ändern, daher behauptet dieser Artikel nicht, dass das Fehlen universell oder dauerhaft undokumentiert sei.
Planen Sie das getestete Setup als zwei Schritte: erst die Node-Pakete installieren, dann den Browser, den der Playwright-Pfad verwendet. Prüfen Sie die aktuellen Einrichtungsanweisungen für Crawlee und Playwright erneut für die Versionen und Plattformen, die Sie tatsächlich einsetzen.
Praxis: dieselbe Seite, zwei sehr unterschiedliche Antworten

Der Kerntest schickte denselben JavaScript-gerenderten Fixture ĂĽber beide Crawler. URL und Zielfelder waren identisch; die Extraktionsprimitiven nicht.
Beim lokalen Fixture lieferte CheerioCrawler 0 Zielkarten, weil sie im rohen HTML nicht vorhanden waren. PlaywrightCrawler wartete auf #dynamic-products article.product-card und lieferte dann alle 8 erwarteten Karten sowie einen Screenshot. Dieses Ergebnis belegt die Vollständigkeit der ausgewählten Felder auf Fixture-Ebene nach diesem Wait; es bedeutet nicht, dass ein Browser jeden denkbaren Seitenzustand sieht. Die Rohdateien und der Screenshot liegen im Benchmark-Repo.

Auf der öffentlichen Quotes-to-Scrape-JS-Seite fand CheerioCrawler 0 Ziel-Zitate und PlaywrightCrawler wartete auf .quote, bevor es 10 extrahierte. Das bestätigt dieselbe HTTP-vs.-Browser-Grenze auf einem öffentlichen Ziel, während sich Crawler-Klasse, Handler-Kontext, Wait-Bedingung und Extraktionsprimitiv zwischen den beiden Pfaden unterscheiden.
Die nützliche Schlussfolgerung ist enger gefasst: Prüfen Sie nach dem HTTP-Pfad, ob alle benötigten Felder vorhanden sind, und wechseln Sie zu einem Browser-Crawler, wenn die rohe Antwort sie nicht enthält. Der Browser-Handler muss außerdem auf eine Bedingung warten, die an diese Felder gebunden ist.
Der HTTP-Pfad lieferte alle erwarteten Datensätze auf den kontrollierten statischen Katalog- und Artikel-Fixtures, dekodierte alle acht erwarteten Elemente aus einer direkten JSON-Antwort, durchlief einen begrenzten 11-Seiten-Graphen und leitete eine 500-Antwort an failedRequestHandler weiter. Das sind getrennte Fähigkeitsprüfungen und kein einzelner Genauigkeitswert. Gegen die öffentliche Books-to-Scrape-Seite lieferte der konfigurierte Selektor als Smoke Test 20 Produkte.
| Test | Engine | Ergebnis |
|---|---|---|
| Statische Extraktion: Katalog + Paginierung | CheerioCrawler | 12/12 erwartete Produkte |
| Artikel-Extraktion | CheerioCrawler | Titel + 3/3 Absätze |
| Transport: direkte JSON-Antwort | CheerioCrawler | 8/8 erwartete Produkte |
| Traversierung: interner Link-Graph | CheerioCrawler | 11 Seiten, Tiefen {0:1, 1:3, 2:7} |
| Fehlerweiterleitung: HTTP 500 | CheerioCrawler | Status erreichte den Fehler-Handler |
| Rendering: lokaler Fixture | CheerioCrawler | 0 Zielkarten im rohen HTML |
| Rendering: lokaler Fixture | PlaywrightCrawler | 8/8 nach Warten auf Zielselektor |
| Rendering: Quotes JS | CheerioCrawler | 0 Ziel-Zitate im rohen HTML |
| Rendering: Quotes JS | PlaywrightCrawler | 10 nach Warten auf Zielselektor |
Die vollständigen Laufzeiten und Werte pro Test stehen in results/crawlee-test-summary.json.
Jetzt zu den ehrlichen Einschränkungen, denn ein einzelner Testlauf auf einem einzelnen Rechner hat Grenzen, und ich tue nicht so, als wären sie nicht da. Das sind Zeitmessungen, keine Benchmarks — ein Rechner, je ein Lauf, also sollte man die höheren Kosten pro Seite des Browser-Pfads als „spürbar langsamer als die subsekündigen Cheerio-Läufe“ verstehen, nicht als veröffentlichte Kennzahl. Und es gibt eine ganze Reihe von Dingen, die ich in diesem Durchgang nicht getestet habe: Proxy-Rotation, Session-Pools, groß angelegte Läufe mit Hunderten bis Tausenden von Seiten, Persistenz und Wiederaufnahme von RequestQueue nach einem Absturz, die Puppeteer-Engine sowie die Export-Ergonomie von Dataset/KeyValueStore (ich habe die Exporte hier manuell geschrieben). Ich kann die Zwei-Engine-Story und die Genauigkeit auf Fixture-Ebene bestätigen. Ich kann aber nicht für Skalierung oder Anti-Blocking-Verhalten bürgen, also werde ich das auch nicht.
Was gemeinsam ist und was sich ändern muss

Die gemeinsame Oberfläche ist die Crawl-Orchestrierung. Beide Crawler-Klassen akzeptieren einen requestHandler und stellen run() bereit. Queues, Request-Metadaten, Link-Erkennung, Fehler-Hooks und Storage-Konzepte lassen sich konsistent um beide Ausführungspfade herum organisieren. Das verringert die Infrastruktur, die ein Team neu lernen muss, wenn ein Ziel doch einen Browser verlangt.
Die Oberfläche für den Seitenzugriff ist nicht gemeinsam. Ein CheerioCrawler-Handler erhält Cheerio-orientierte Zugriffe wie $ und kann ohne Browser mit Response-Bodies arbeiten. Der getestete PlaywrightCrawler-Handler erhält page; er wartet auf einen Selektor und wertet im Browser-DOM aus. Selbst wenn beide Handler dasselbe Record-Schema ausgeben, erreichen sie es über unterschiedliche APIs. Ein wiederverwendbarer Adapter könnte einen Teil dieses Unterschieds verbergen, aber dieser Testaufbau hat keinen implementiert oder demonstriert.
Diese Unterscheidung ist wichtig für die Aufwandsschätzung. Ein Wechsel der Crawler-Klasse kann Queue, Dataset und URL-Policy beibehalten, dennoch können sich Selektoren, Bereitschaftsprüfungen, Screenshots, Interaktionsschritte und Fehlerbehandlung ändern. Der Artikel behandelt daher „gemeinsame Crawl-Infrastruktur“ als den verifizierten Vorteil und weist die Behauptung einer „Ein-Zeile-Migration“ als ungesichertes Versprechen zurück.
Ein praktischer Ablauf zur Engine-Auswahl
Verwenden Sie zuerst den HTTP-Pfad, wenn das zurückgelieferte HTML oder eine direkte JSON-Antwort die benötigten Felder enthält. Definieren Sie einen Vollständigkeitsvertrag — erforderliche Schlüssel, Mindestanzahl an Einträgen oder einen Zielselektor — und schlagen Sie explizit fehl, wenn dieser nicht erfüllt ist. Ein leeres Array ist kein Beweis dafür, dass die Seite keine Daten hat; in den beiden JavaScript-Fällen hier bedeutete es nur, dass die gewählte Darstellung die Zielelemente nicht enthielt.
| Zielbedingung | Starten mit | Eskalieren, wenn |
|---|---|---|
| Erforderliche Felder sind im zurĂĽckgegebenen HTML vorhanden | CheerioCrawler | Erforderliche Selektoren oder Felder fehlen |
| Eine reproduzierbare JSON-Antwort enthält die Daten | CheerioCrawler | Die Anfrage hängt von Browser-zustand ab |
| Die Seite fĂĽgt Zielelemente erst nach der AusfĂĽhrung ein | PlaywrightCrawler | Nicht anwendbar; definieren Sie eine zielbezogene BereitschaftsprĂĽfung |
| Die Ziel-Mischung ist unbekannt | Zuerst HTTP mit Vollständigkeitsprüfung | Prüfung schlägt mit einem typisierten „Darstellung unvollständig“-Ergebnis fehl |
Geben Sie diesen typisierten Fehler an einen Browser-Handler weiter, wenn Ausführung erforderlich ist. In diesem Testaufbau wartete die lokale Seite auf #dynamic-products article.product-card, während die öffentliche Quotes-Seite auf .quote wartete. Diese Bedingungen sind Teil des Extraktionsvertrags. Ein generisches Load-Event würde nicht belegen, dass die Anwendungsdaten tatsächlich angekommen sind, und der Test stützt keine universelle Wait-Regel.
Nach der Eskalation sollte das Ausgabeschema stabil bleiben, auch wenn sich die DOM-Primitiven unterscheiden. Erfassen Sie, welche Engine das Ergebnis erzeugt hat, welche Bereitschaftsbedingung erfüllt wurde und ob die Validierung der Pflichtfelder erfolgreich war. So wird ein HTTP-zu-Browser-Fallback beobachtbar, statt fehlende Felder stillschweigend als akzeptierte Datensätze durchzuwinken.
Und schließlich: Behandeln Sie Browser-Installation und Betriebskosten als Deployment-Eingaben. Die beobachteten etwa 82 MiB sind nur als lokale Größenordnung nützlich; messen Sie den exakten Browser-Build, die Plattform, das Cache-Verhalten und den Image-Einfluss in Ihrer Umgebung. Proxy-Rotation, Sessions, Persistenz, Absturz-Wiederaufnahme und nachhaltige Parallelität brauchen weiterhin eigene Tests, bevor dieser Fixture eine Produktionsentscheidung stützen kann.
Vor- und Nachteile
Vorteile:
- HTTP- und Browser-Crawler teilen sich Lifecycle-Konzepte, bieten aber enginespezifische Extraktionskontexte.
- HTTP-Extraktion mit hoher Trefferquote bei statischen Katalogen, Artikeln und JSON-APIs.
- Gemeinsame Infrastruktur in beiden Engines:
RequestQueue,enqueueLinksmit Tiefenkontrolle,Dataset. - Der Browser-Pfad fĂĽhrte die Fixture-Skripte aus und stellte in den beiden JS-gerenderten Tests alle erwarteten Zielobjekte wieder her.
- Sauberes Fehlerhandling — HTTP 500 wurde ohne Absturz sichtbar.
- Apache-2.0-Lizenz; Downstream-Nutzer sollten die Hinweise und Pflichten zur Namensnennung prĂĽfen.
Nachteile:
- In der getesteten Umgebung brauchte die Browser-Engine eine separate Chromium-Installation; ohne sie startete
PlaywrightCrawlernicht. - Der HTTP-Pfad kann Zielelemente, die im rohen HTML fehlen, nicht sichtbar machen; ohne Vollständigkeitsprüfung kann das wie ein gültiges leeres Ergebnis wirken.
- Der Browser-Pfad bringt ein zusätzliches Browser-Binary und in diesem Lauf höhere lokale Kosten pro Seite mit sich; Größe und Laufzeit variieren je nach Build und Plattform.
- Standardläufe hinterlassen ein
storage/-Verzeichnis auf der Festplatte. - Nur Node/TypeScript — keine Hilfe, wenn Ihr Stack Python ist.
Für wen es passt — und wer lieber verzichten sollte
Crawlee eignet sich für Node- oder TypeScript-Teams, die HTTP- und Browser-Crawling unter gemeinsamen Queue- und Lifecycle-Konzepten brauchen. Ein praktikabler Weg ist, mit dem HTTP-Crawler zu beginnen, Pflichtfelder zu validieren und einen typisierten Vollständigkeitsfehler an einen Browser-Handler mit zielbezogener Bereitschaftsbedingung weiterzureichen. Der DOM-Zugriff im Handler ist enginespezifisch, auch wenn Queue und Link-Erkennung gemeinsam genutzt werden.
Setzen Sie Ihre Erwartungen neu oder schauen Sie sich eine andere Lösung an, wenn Sie ein Python-Stack betreiben (Crawlee ist Node/TS — es gibt zwar einen separaten Python-Port, aber dieser Test bezog sich auf die Node-Bibliothek), wenn alle Ihre Ziele statisch sind und Ihnen ein schlankerer Spezial-HTTP-Scraper lieber wäre, oder wenn Sie belegte Skalierung brauchen — Proxy-Rotation, Session-Pools, Wiederaufnahme nach Absturz — was dieser Praxistest nicht abgedeckt hat. Und wenn Sie zu PlaywrightCrawler greifen, installieren Sie Chromium zuerst, sonst läuft es schlicht nicht.
Alternativen, einschlieĂźlich der Rolle von Thunderbit
Crawlee ist Open-Source-Software, die Sie selbst betreiben und warten. Es gibt keine nutzungsabhängige Vendor-Gebühr, aber Browser-Compute, Bandbreite, Proxies, Storage, Observability und Engineering bleiben Betriebskosten. Sie tragen die Verantwortung für Crawler-Auswahl, Browser-Binary, Storage-Zustand und Bereitschaftslogik.
Verwandte Rezension: scrapy-playwright review.
Ein verwalteter Extraktionsdienst verlagert die Beschaffung und das Formen des Schemas auf einen Anbieter. Wir bauen Thunderbit, haben es aber nicht gegen diese Fixtures ausgeführt, daher liefert dieser Artikel keinen Vergleich zu Qualität, Latenz, Funktionsparität oder Kosten. Die relevante Frage ist, ob Ihr Team die Kontrolle von Crawlee im Prozess oder eine Service-Grenze pro Aufruf bevorzugt.
Verwandte Benchmark-Analysen: der vollständige Open-Source-Scraper-Vergleich, Playwright vs Puppeteer auf denselben Seiten und Scrapys No-Browser-Request-Replay-Review.
Thunderbit fĂĽr Webdaten-Extraktion testen
Fazit
Crawlee ist eine starke Option fĂĽr Node- oder TypeScript-Teams, die eine gemeinsame Crawl-Orchestrierung fĂĽr HTTP und Browser-AusfĂĽhrung wollen. Die getesteten Handler waren nicht austauschbar: Der Wechsel zu Playwright erforderte page, ein Warten auf den Zielselektor und eine Extraktion im Browser. Proxy-, Session-, Persistenz-, Resume- und Skalierungsfragen bleiben offen.
Thunderbit fĂĽr Webdaten-Extraktion testen Get Started Free
FAQs
Worin besteht der eigentliche Unterschied zwischen Crawlees zwei Crawlern?
CheerioCrawler ruft HTML über HTTP ab und führt kein JavaScript aus. PlaywrightCrawler steuert Chromium und kann die Skripte der Seite ausführen und Screenshots erstellen, allerdings mit höheren lokalen Kosten pro Seite. Beide teilen sich Lifecycle-Konzepte, aber nicht identische Handler-Kontexte: In diesem Testaufbau wurde auf dem HTTP-Pfad $ verwendet und auf dem Playwright-Pfad page, ein Wait auf den Zielselektor sowie Auswertung im Browser.
Warum startet PlaywrightCrawler nicht, nachdem ich Crawlee installiert habe?
In der getesteten Umgebung brachte die Paketinstallation kein Browser-Executable mit. Das Installieren von Chromium mit npx playwright install chromium behob den Startfehler. Die beobachtete Nutzlast lag bei ungefähr 82 MiB, aber die ursprüngliche Messung hat nicht festgehalten, ob das Transfer- oder Festplattengröße war — messen Sie es also für Ihre Plattform und Ihren Build neu.
Kann CheerioCrawler JavaScript-gerenderte Seiten scrapen?
Es kann das JavaScript der Seite nicht ausführen. Es kann jedoch einen zugänglichen JSON-Endpunkt anfragen, den der Client verwendet, wie der direkte Antwort-Fixture zeigt. Wenn die benötigten Daten erst nach Browser-Ausführung vorhanden sind, nutzen Sie einen Browser-Crawler und eine Bereitschaftsbedingung, die an diese Felder gekoppelt ist.
Ist Crawlee für normale statische Extraktion genau? Auf den kontrollierten Fixtures lieferten die Handler 12/12 erwartete Katalogprodukte, 3/3 erwartete Artikelabsätze und 8/8 erwartete direkte JSON-Elemente. Das sind Prüfungen auf Fixture-Vollständigkeit, kein allgemeiner Genauigkeitswert für ungetestete Websites.
Ist Crawlee für kommerzielle Nutzung kostenlos? Es wird unter Apache-2.0 veröffentlicht. Bestätigen Sie die aktuelle Lizenz im Repository und prüfen Sie die Hinweise und Namensnennungspflichten für Ihre Verteilung.
Vor einer produktiven Einführung sollten Sie die Teile testen, die dieser Fixture offen lässt: wiederholte Parallelität auf repräsentativen Seiten, Proxy- und Session-Verhalten, persistente Wiederaufnahme der Queue nach Unterbrechung, Bereinigung von Browser-Prozessen und Dataset-Export im Fehlerfall. Bewahren Sie die aufgelöste Browser-Version und den Installationspfad zusammen mit diesen Ergebnissen auf. Die beiden Crawler-Klassen reduzieren Unterschiede in der Orchestrierung, aber sie ersetzen nicht engine-spezifische Bereitschaftsprüfungen, Ressourcenbudgets und operatives Fehlermanagement.


