Crawlee-review: Quotes to Scrape leverde 0 op via HTTP en 10 in Chromium

Laatst bijgewerkt op August 17, 2026
Crawlee-review: Quotes to Scrape leverde 0 op via HTTP en 10 in Chromium
AI-samenvatting
Wat Crawlee zo bruikbaar maakt, is dat de crawl-orkestratie zowel HTTP-parsing als uitvoering in de browser ondersteunt. Daardoor kan dezelfde URL andere resultaten opleveren, afhankelijk van de gekozen crawler en de gereedheidsvoorwaarde. Op de openbare Quotes to Scrape JS-pagina vond CheerioCrawler 0 doelquotes, terwijl PlaywrightCrawler er 10 vond nadat op .quote was gewacht. De crawl-lifecycle is vergelijkbaar, maar dit was niet een simpele wissel van alleen de class: de Cheerio-handler gebruikte $, terwijl de Playwright-handler page, een expliciete wachttijd en extractie aan de browserkant gebruikte. Crawlee is een sterke kandidaat voor Node- of TypeScript-teams die gedeelde crawl-orkestratie willen voor zowel HTTP als browseruitvoering.

Wat Crawlee zo nuttig maakt, is dat de crawl-orkestratie zowel HTTP-parsing als browser-executie ondersteunt. Daardoor kan dezelfde URL verschillende resultaten opleveren, afhankelijk van de gekozen crawler en de voorwaarde waarop je de pagina als “klaar” beschouwt.

Op de openbare Quotes to Scrape JS-pagina vond CheerioCrawler 0 doelquotes, terwijl PlaywrightCrawler er 10 vond nadat werd gewacht op .quote. De crawl-levenscyclus lijkt op elkaar, maar dit was geen simpele éénregelige wissel van alleen de class: de Cheerio-handler gebruikte $, terwijl de Playwright-handler page, een expliciete wachtstap en browser-side extractie gebruikte.

Wat Crawlee daadwerkelijk is

Crawlee (het project apify/crawlee, versie 3.17.0) is een library voor webscraping en browserautomatisering voor Node.js en TypeScript. Het ondersteunt HTTP-crawling met Cheerio of JSDOM, en browser-crawling met Playwright of Puppeteer. Het project gebruikt Apache-2.0; controleer de verplichtingen rond vermelding en attributie voor jouw distributie.

Het mentale model dat hier telt, is het scheiden van “de pagina ophalen” en “de pagina lezen”. De ene route downloadt ruwe HTML en voert geen JavaScript uit. De andere start Chromium en kan de scripts van de pagina uitvoeren, maar heeft nog steeds een geschikte gereedheidsvoorwaarde nodig en kan content missen die achter interactie zit, lazy-loaded is, in shadow DOM staat, via een mislukte API wordt geladen of door botbescherming wordt geblokkeerd. Crawlee biedt voor deze paden vergelijkbare levenscyclusconcepten, niet uitwisselbare DOM-primitieven.

Dat is precies het deel dat je moet snappen voordat je ook maar één selector schrijft, want de keuze tussen die twee engines bepaalt of je scraper op een bepaalde site data oplevert of helemaal niets.

Belangrijkste functies: twee engines, één API-oppervlak

Crawlee two engines one API

CheerioCrawler haalt HTML op en parseert die met Cheerio; PlaywrightCrawler bestuurt Chromium en kan screenshots maken. Beide gebruiken een requestHandler, bieden run() aan en delen crawlconcepten zoals queues en link discovery. Hun handler-context verschilt: in het getest Cheerio-pad werd geëxtraheerd via $, terwijl het browserpad page, waitForSelector en $$eval gebruikte. De queue- en levenscyclusonderdelen blijven vertrouwd, maar de extractiecode heeft mogelijk een adapter of herschrijving nodig.

Daaronder regelt Crawlee de basis die een echte crawl nodig heeft. Een RequestQueue beheert de frontier van URL’s die bezocht moeten worden, voorkomt duplicaten en houdt bij wat al gedaan is. enqueueLinks ontdekt en voegt nieuwe URL’s toe (met selector- en same-hostname-filtering), zodat een crawl zichzelf kan uitbreiden. Een Dataset verzamelt je gescrapete records voor export. Standaard slaat Crawlee dit allemaal lokaal op in een storage/-map op schijf — handig om te hervatten, en iets minder handig als je voor het eerst een storage/-map in je project ziet verschijnen zonder dat je daar om vroeg (mijn testopstelling stuurde dit naar een tijdelijke map en zette persistentie uit om de test schoon te houden).

De onderdelen zijn op zichzelf niet zo bijzonder. Het punt is dat ze door beide engines worden gedeeld, waardoor queue, link discovery en dataset hetzelfde werken, of je nu via HTTP crawlt of via een browser. Je leert één API en krijgt twee ophaalstrategieën.

Setup: de browser die apart geïnstalleerd moet worden

De geteste installatie bevatte na het installeren van de packages geen Chromium-executable.

Crawlee setup install weight

npm install crawlee playwright verliep bij mij zonder problemen — 85 packages, 0 kwetsbaarheden, geen gedoe. Als je daar stopt en een CheerioCrawler draait, werkt alles gewoon, want HTTP-crawling heeft geen browser nodig.

In deze omgeving moest Chromium apart worden geïnstalleerd met npx playwright install chromium; zonder dat mislukte het starten van PlaywrightCrawler. De gemeten browser-payload was ongeveer 82 MiB, maar in de originele notities staat niet meer of dat overdrachtsgrootte of schijfgrootte was. Het is een observatie uit een specifieke machine-opstelling, geen vast productkenmerk. Documentatiepaden en pakketgedrag kunnen veranderen, dus dit artikel claimt niet dat de omissie universeel of blijvend ongedocumenteerd is.

Zie de geteste setup dus als twee stappen: installeer eerst de Node-packages, en installeer daarna de browser die het Playwright-pad gebruikt. Check altijd opnieuw de actuele setup-instructies van Crawlee en Playwright voor de versies en het platform waarop je uitrolt.

Hands-on: dezelfde pagina, twee heel verschillende antwoorden

Crawlee Cheerio 0 vs Playwright 8/8

De kernproef stuurde dezelfde JavaScript-gerenderde fixture langs beide crawlers. De URL en doelfvelden waren hetzelfde; de extractieprimitieven niet.

Op de lokale fixture gaf CheerioCrawler 0 doelkaarten terug, omdat die ontbraken in de ruwe HTML. PlaywrightCrawler wachtte op #dynamic-products article.product-card en gaf daarna alle 8 verwachte kaarten terug, plus een screenshot. Dat resultaat bevestigt dat de geselecteerde velden na die wachttijd compleet waren op fixture-niveau; het betekent niet dat een browser elke mogelijke paginastatus ziet. De ruwe bestanden en screenshot staan in de benchmarkrepo.

Crawlee public Quotes JS ten

Op de openbare Quotes to Scrape JS-pagina vond CheerioCrawler 0 doelquotes, terwijl PlaywrightCrawler eerst op .quote wachtte en er daarna 10 uit haalde. Dit bevestigt dezelfde HTTP-versus-browsergrens op een publiek doel, terwijl de crawlerclass, handlercontext, wachtvoorwaarde en extractieprimitief tussen de twee paden allemaal verschillen.

De bruikbare conclusie is smaller: valideer de vereiste velden na het HTTP-pad, en schakel over naar een browsercrawler wanneer de ruwe response ze niet bevat. De browser-handler moet bovendien wachten op een voor die velden relevante conditie.

Het HTTP-pad leverde alle verwachte records op in de gecontroleerde statische catalogus- en artikelfixtures, decodeerde alle acht verwachte items uit een directe JSON-response, doorliep een begrensde grafiek van 11 pagina’s en stuurde één 500-response naar failedRequestHandler. Dit zijn losse capaciteitschecks en geen enkel totaalcijfer voor nauwkeurigheid. Tegen de openbare Books to Scrape-pagina gaf de ingestelde selector 20 producten terug als smoke test.

TestEngineResultaat
Statische extractie: catalogus + pagineringCheerioCrawler12/12 verwachte producten
Artikel-extractieCheerioCrawlertitel + 3/3 paragrafen
Transport: directe JSON-responseCheerioCrawler8/8 verwachte producten
Traversal: interne-linkgrafiekCheerioCrawler11 pagina’s, dieptes {0:1, 1:3, 2:7}
Foutafhandeling: HTTP 500CheerioCrawlerstatus bereikte failure handler
Rendering: lokale fixtureCheerioCrawler0 doelkaarten in ruwe HTML
Rendering: lokale fixturePlaywrightCrawler8/8 na wachten op doelselector
Rendering: Quotes JSCheerioCrawler0 doelquotes in ruwe HTML
Rendering: Quotes JSPlaywrightCrawler10 na wachten op doelselector

Volledige timings en detailcijfers per test staan in results/crawlee-test-summary.json.

Nu de eerlijke kanttekeningen, want een test op één machine en één run heeft grenzen en daar doe ik niet geheimzinnig over. Dit zijn timings, geen benchmarks — één machine, één run per test, dus beschouw de hogere per-page kost van het browserpad als “merkbaar trager dan sub-second Cheerio-runs”, niet als een gepubliceerd cijfer. En er is een hele stapel zaken die ik in deze test niet heb meegenomen: proxy-rotatie, session pools, grootschalige runs van honderden tot duizenden pagina’s, persistentie en hervatten na crash van RequestQueue, de Puppeteer-engine en de export-ervaring van Dataset/KeyValueStore (ik heb exports hier handmatig geschreven). Ik kan instaan voor het verhaal met de twee engines en de nauwkeurigheid op fixture-niveau. Ik kan niet instaan voor schaal of anti-blocking gedrag, dus dat ga ik ook niet doen.

Wat gedeeld is, en wat moet veranderen

Crawlee one-line engine switch

Het gemeenschappelijke oppervlak is de crawl-orkestratie. Beide crawlerclasses accepteren een requestHandler en bieden run() aan. Queues, requestmetadata, link discovery, failure hooks en storage-concepten kunnen op beide uitvoerpaden op een consistente manier worden ingericht. Daardoor hoeft een team minder infrastructuur opnieuw te leren wanneer één target een browser nodig heeft.

Het pagina-toegangssvlak is níet gemeenschappelijk. Een CheerioCrawler-handler krijgt Cheerio-georiënteerde toegang zoals $ en kan werken met response bodies zonder browser. De geteste PlaywrightCrawler-handler krijgt page; die wacht op een selector en evalueert via de browser-DOM. Zelfs als beide handlers hetzelfde recordschema opleveren, bereiken ze dat via verschillende API’s. Een herbruikbare adapter zou een deel van dit verschil kunnen verbergen, maar deze testopzet heeft zo’n adapter niet geïmplementeerd of gedemonstreerd.

Dat onderscheid is belangrijk voor inschattingen. Het wijzigen van de crawlerclass kan queue, dataset en URL-beleid behouden, maar selectors, gereedheidscontroles, screenshots, interactiestappen en foutafhandeling kunnen nog steeds veranderen. Daarom behandelt dit artikel “gedeelde crawl-infrastructuur” als het bewezen voordeel en wijst het “one-line migratie” af als een onbewezen belofte.

Een praktische flow voor engine-selectie

Begin met het HTTP-pad wanneer de teruggegeven HTML of een directe JSON-response de vereiste velden bevat. Definieer een volledigheidscontract — verplichte keys, minimaal aantal items of een doelselector — en laat expliciet falen wanneer daar niet aan wordt voldaan. Een lege array is geen bewijs dat de pagina geen data heeft; in de twee JavaScript-cases hier betekende het dat de gekozen representatie de doelitems niet bevatte.

DoelvoorwaardeBegin metSchakel over wanneer
Vereiste velden zitten in de geretourneerde HTMLCheerioCrawlerVereiste selectors of velden ontbreken
Een reproduceerbare JSON-response bevat de dataCheerioCrawlerDe request hangt af van browser-only state
De pagina voegt doelitems pas toe na executiePlaywrightCrawlerNiet van toepassing; definieer een targetspecifieke gereedheidscheck
De doelmix is onbekendEerst HTTP, met volledigheidsvalidatieValidatie faalt met een getypte “representatie onvolledig”-uitkomst

Escaleer die getypte fout vervolgens naar een browser-handler wanneer executie nodig is. In deze testopzet wachtte de lokale pagina op #dynamic-products article.product-card, terwijl de openbare quotes-pagina op .quote wachtte. Die voorwaarden maken deel uit van het extractiecontract. Een generieke load event bewijst niet dat de applicatiedata is aangekomen, en deze test ondersteunt geen universele regel voor wachten.

Houd na de escalatie het outputschema stabiel, ook al verschillen de DOM-primitieven. Noteer welke engine het resultaat produceerde, welke gereedheidsvoorwaarde is geslaagd en of de validatie van verplichte velden slaagde. Zo wordt een HTTP-naar-browser fallback zichtbaar, in plaats van dat ontbrekende velden stilzwijgend als geldige records worden geaccepteerd.

Beschouw tot slot de browserinstallatie en operationele kosten als deployment-inputs. De observatie van ongeveer 82 MiB is alleen bruikbaar als lokale orde van grootte; meet de exacte browserbuild, het platform, cachegedrag en de impact van images in jouw omgeving. Proxy-rotatie, sessions, persistentie, crash recovery en aanhoudende concurrency verdienen nog steeds hun eigen tests voordat deze fixture iets zegt over een productiekeuze op schaal.

Voor- en nadelen

Voordelen:

  • HTTP- en browsercrawlers delen levenscyclusconcepten, terwijl ze engine-specifieke extractiecontexten bieden.
  • Nauwkeurige HTTP-extractie op statische catalogi, artikelen en JSON-API’s.
  • Gedeelde infrastructuur tussen beide engines: RequestQueue, enqueueLinks met dieptecontrole, Dataset.
  • Het browserpad voerde de fixture-scripts uit en herstelde alle verwachte doelitems in de twee JS-gerenderde tests.
  • Schone foutafhandeling — HTTP 500 kwam zichtbaar door zonder crash.
  • Apache-2.0-licentie; downstreamgebruikers moeten de verplichtingen rond vermelding en attributie controleren.

Nadelen:

  • In de geteste omgeving had de browserengine een aparte Chromium-installatie nodig; zonder die installatie startte PlaywrightCrawler niet.
  • Het HTTP-pad kan geen doelitems tonen die ontbreken in ruwe HTML; zonder volledigheidsvalidatie kan dat eruitzien als een legitiem leeg resultaat.
  • Het browserpad brengt een extra browserbinary en hogere lokale per-page kosten mee in deze run; grootte en timing verschillen per build en platform.
  • Standaardruns laten een storage/-map achter op schijf.
  • Alleen Node/TypeScript — geen hulp als je stack Python is.

Voor wie het is — en wie het beter kan overslaan

Crawlee past bij Node- of TypeScript-teams die zowel HTTP- als browsercrawling nodig hebben onder gedeelde queue- en levenscyclusconcepten. Een praktische route is om eerst de HTTP-crawler te proberen, de vereiste velden te valideren en een getypte completeness-failure door te geven aan een browser-handler met een targetspecifieke gereedheidsvoorwaarde. De DOM-toegangscode van de handler is engine-specifiek, ook al worden queue- en link-discovery-infrastructuur gedeeld.

Stel je verwachtingen bij, of kijk elders, als je een Python-shop bent (Crawlee is Node/TS — er bestaat een aparte Python-port, maar deze test gebruikte de Node-library), als al je targets statisch zijn en je liever een lichtere single-purpose HTTP-scraper wilt, of als je bewezen gedrag op schaal nodig hebt — proxy-rotatie, session pools, hervatten na crash — wat deze hands-on niet heeft afgedekt. En als je PlaywrightCrawler wilt gebruiken, installeer dan eerst Chromium, anders draait het simpelweg niet.

Alternatieven, inclusief waar Thunderbit past

Crawlee is open-source software die je zelf draait en onderhoudt. Er is geen vendor-fee per call, maar browsercompute, bandbreedte, proxies, opslag, observability en engineering blijven operationele kosten. Je bent zelf verantwoordelijk voor de keuze van de crawler, de browserbinary, storage-state en de gereedheidslogica.

Gerelateerde review: scrapy-playwright review.

Een beheerde extraction-service verschuift acquisitie en schema-opbouw naar een leverancier. Wij bouwen Thunderbit, maar hebben het niet op deze fixtures getest, dus dit artikel doet geen uitspraak over kwaliteit, latency, feature-pariteit of kostenvergelijking. De relevante vraag is of jouw team de in-process controle van Crawlee wil, of een per-call servicegrens.

Gerelateerde benchmarkreviews: de volledige vergelijking van open-source scrapers, Playwright versus Puppeteer op dezelfde pagina’s en Scrapy’s no-browser request-replay review.

Probeer Thunderbit voor webdata-extractie

Conclusie

Crawlee is een sterke kandidaat voor Node- of TypeScript-teams die gedeelde crawl-orkestratie willen voor zowel HTTP als browserexecutie. De geteste handlers waren niet uitwisselbaar: overschakelen naar Playwright vereiste page, een doelselector-wachtstap en browser-side extractie. Proxy, sessions, persistentie, hervatten en gedrag op grote schaal blijven open vragen.

Probeer Thunderbit voor webdata-extractie Get Started Free

FAQ’s

Wat is nu precies het verschil tussen Crawlee’s twee crawlers? CheerioCrawler haalt HTML op via HTTP en voert geen JavaScript uit. PlaywrightCrawler bestuurt Chromium en kan scripts op de pagina uitvoeren en screenshots maken, tegen hogere lokale per-page kosten. Ze delen levenscyclusconcepten, maar niet identieke handler-contexten: deze testopzet gebruikte $ op het HTTP-pad en page, een wachtstap op de doelselector en browser-side evaluatie op het Playwright-pad.

Waarom wil PlaywrightCrawler niet draaien nadat ik Crawlee heb geïnstalleerd? In de geteste omgeving leverde de package-installatie geen browser-executable mee. Het installeren van Chromium met npx playwright install chromium loste de launch-fout op. De gemeten payload was ongeveer 82 MiB, maar de originele meting maakte niet duidelijk of dat overdrachts- of schijfgrootte was, dus meet het opnieuw voor jouw platform en build.

Kan CheerioCrawler JavaScript-gerenderde pagina’s scrapen? Nee, het kan de JavaScript van de pagina niet uitvoeren. Het kan wel een toegankelijk JSON-endpoint opvragen dat door de client wordt gebruikt, zoals de direct-response fixture laat zien. Wanneer de vereiste data pas na browserexecutie beschikbaar is, gebruik dan een browsercrawler en een gereedheidsvoorwaarde die aan die velden is gekoppeld.

Is Crawlee nauwkeurig voor normale statische extractie? In de gecontroleerde fixtures leverden de handlers 12/12 verwachte catalogusproducten, 3/3 verwachte artikelparagrafen en 8/8 verwachte direct-JSON-items op. Dit zijn checks op fixture-compleetheid, geen algemene nauwkeurigheidsscore voor ongeteste sites.

Is Crawlee gratis voor commercieel gebruik? Het is uitgebracht onder Apache-2.0. Bevestig de actuele licentie in de repository en controleer de verplichtingen rond vermelding en attributie voor jouw distributie.

Test vóór productiegebruik ook de onderdelen die deze fixture openlaat: herhaalde concurrency op representatieve pagina’s, proxy- en sessiongedrag, persistente queue-herstel na onderbreking, cleanup van browserprocessen en dataset-export bij fouten. Bewaar de gebruikte browserversie en installatiewijze samen met die resultaten. De twee crawlerclasses verminderen verschillen in orkestratie, maar nemen de noodzaak niet weg van enginespecifieke gereedheidscontroles, resourcebudgetten en operationele foutafhandeling.

Ke
Ke
CTO bij Thunderbit | Senior Data Scientist & ML-expert Met bijna tien jaar ervaring in machine learning en data science is Ke Shen alumnus van Columbia University en voormalig Senior Data Scientist bij Walmart Labs. Met diepgaande, door vakgenoten erkende expertise in Python, R, Java en statistiek deelt hij praktijkgerichte inzichten over hoe je complexe AI-algoritmen van theorie naar productieklare architectuur brengt.
Inhoudsopgave
Thunderbit · AI-webdata-agent

Gegevens extraheren van elke pagina in 1 klik

Vertrouwd door meer dan 250.000 gebruikers
gratis abonnement beschikbaar
Van webpagina naar spreadsheet
Beschrijf wat je nodig hebt — Thunderbit's AI Agent scrapt het en exporteert het naar Excel, Google Sheets, Airtable of Notion. Gratis om te starten.
Chrome Store Rating
PRODUCT HUNT#1 Product of the Week