De flesta stöter på Crawlee när de egentligen försöker svara på en annan fråga: “vilken headless browser ska jag använda?” Det är fel fråga, och Crawlee är skälet. Det är ingen webbläsare. Det är ett Node/TypeScript-ramverk som kopplar in en webbläsare när du behöver det, och hoppar över den när du inte gör det.
Jag ägnade ett par dagar åt att köra Crawlee 3.17.0 mot en kontrollerad uppsättning testfall och några publika demosajter, på Node v22.22.3 och macOS. Den stora poängen — ett bibliotek, ett API, antingen en HTTP-crawler eller en riktig webbläsare under huven — var det jag ville stresstesta mest, eftersom det är just det löftet som avgör om Crawlee är värt att lägga in i sin stack eller om man lika gärna kan använda Playwright direkt. Kort sagt: historien om två motorer håller, med några asterisker som jag kommer till.
Vad Crawlee faktiskt är (och inte är)
Crawlee beskriver sig som ett bibliotek för web scraping och webbläsarautomatisering i Node.js, byggt för att göra crawlers mer pålitliga. Den officiella позициониeringen är bred: extrahera data för AI, LLM:er, RAG eller GPT:er; ladda ner HTML-, PDF-, JPG-, PNG-filer och annat; fungerar med Puppeteer, Playwright, Cheerio, JSDOM och ren HTTP; med eller utan synligt gränssnitt; inklusive proxyrotation. Det är mycket på en gång, så det hjälper att säga vad Crawlee inte är.
Det är ingen renderingmotor. Det har ingen egen webbläsare. När du vill att JavaScript ska köras, styr Crawlee Playwright eller Puppeteer, som i sin tur styr Chromium (eller någon annan webbläsare). Det är heller ingen molntjänst du anropar över nätverket — det är ett beroende du installerar och kör själv. Det Crawlee är, mer exakt, är lagret ovanför hämtaren: crawler-klasserna, request-kön, lagringen och logiken för att följa länkar. Tänk på det som crawl-ramverket, med en utbytbar motor under ytan.
För protokollet: versionen jag testade var 3.17.0 (släppt 2026-06-04), det är TypeScript, licensen är Apache-2.0, och repot låg på ungefär 24,6k stjärnor per 2026-07-09 på apify/crawlee. Stjärnantal rör sig — repot fick 53 till under de två dagar jag följde det — så se den siffran som en ögonblicksbild, inte som ett fast faktum.
De två motorerna: CheerioCrawler vs PlaywrightCrawler
Här är det som gör designen värd sitt pris, och där jag lade mest tid.
CheerioCrawler är HTTP-spåret. Den hämtar rå HTML över nätet och tolkar den med Cheerio — ingen webbläsare, ingen JavaScript-körning, ingen rendering. Den är snabb och billig. PlaywrightCrawler är webbläsarspåret. Den startar riktig Chromium, renderar sidan inklusive allt JavaScript som bygger DOM:en, och kan till och med ta skärmdumpar.
Två olika motorer med faktiskt olika förmågor. Poängen Crawlee gör är att de bär samma kostym. Båda tar en requestHandler. Båda exponerar run(). Båda följer länkar med enqueueLinks. Att gå från den ena motorn till den andra är ett klassbyte, inte en omskrivning — det verifierade jag genom att hålla min extraktionslogik identisk byte för byte och bara byta vilken crawler-klass som omslöt den.

En sak behöver vara tydlig, eftersom det är där likheten tar slut: innehållshandtaget skiljer sig. I en CheerioCrawler-handler får du $ — en statisk, redan parsad DOM som du frågar med jQuery-lik syntax. I en browser-handler får du ett levande page-objekt. Så kön, routing och “lägg in den här datan, följ de där länkarna”-mekaniken är densamma, men raden där du faktiskt läser sidan ser olika ut. Crawlees egen dokumentation säger ungefär samma sak — det gemensamma gränssnittet gäller crawl-operationerna, medan åtkomsten till innehållet är det som varierar.
| Motor | Hur den hämtar | Kör JavaScript? | Mitt test (1 dynamisk sida) | Bäst för |
|---|---|---|---|---|
CheerioCrawler | Rå HTTP + Cheerio-tolkning | Nej | ~0.035s | Statisk HTML, JSON-API:er, hastighet |
PlaywrightCrawler | Riktig Chromium via Playwright | Ja | ~4.967s | JS-renderade sidor, skärmdumpar |
De här tiderna kommer från en enda maskin och en enda körning — inget benchmark, bara en bild av kompromissen. Webbläsarspåret kostade ungefär två storleksordningar mer tid på samma URL. Det är priset för rendering, och därför väljer man inte det som standard.
Testet: samma URL, 0 mot 8/8
Påståenden är billiga. Anledningen till att jag tror på berättelsen om två motorer är att jag kunde få den att falla och sedan laga den genom att byta en enda klass.
Jag byggde ett lokalt dynamiskt testfall — en katalogsida där produktkort injiceras av JavaScript efter laddning, precis den typ av sida som blivit norm i dagens webben. Jag pekade CheerioCrawler mot den. Den gav 0 produktkort. Det är inte en bugg; det är fysik. Cheerio körde aldrig JavaScriptet, så korten fanns aldrig i HTML:en den tolkade. Sedan pekade jag PlaywrightCrawler mot exakt samma URL, ändrade inget annat, och den renderade 8 av 8 produkter och tog en skärmdump som bevis.

För att säkerställa att det inte bara var något eget udda med mitt testfall körde jag samma mönster mot en publik sajt — Quotes to Scrape, en JavaScript-demo som bygger sina citat på klientsidan. Samma resultat åt samma håll: CheerioCrawler såg 0 citat, PlaywrightCrawler hämtade fram 10.

Jag vill vara noggrann med vad detta faktiskt bevisar. Det är en ren reproduktion av ett påstående som Crawlee redan dokumenterar — ramverket har delat samma basklass och gränssnitt mellan crawler-typerna sedan version 3.0. Så detta är verifiering, inte upptäckt. Men det är exakt värdet: marknadsföringsfrasen “ett gränssnitt, HTTP eller webbläsare” stämmer, och här är kvittot från 0 till full data både på ett testfall jag kontrollerar och en sajt jag inte kontrollerar.
När HTTP-spåret vinner
Det vore lätt att läsa avsnittet ovan som “använd alltid webbläsaren”. Gör inte det. Hela poängen med två motorer är att webbläsaren är reservlösningen som kostar mer, inte standardvalet.
På statiskt innehåll var CheerioCrawler både korrekt och snabb. Mitt statiska katalogtest gav 12 av 12 produkter med full träffsäkerhet, med följning av pagination via enqueueLinks({ selector: '.next-page' }), på ungefär 0,155 sekunder. En artikelsida gav sin titel och alla 3 av 3 stycken i brödtexten, och login-/prenumerations-/copyright-texten hölls snyggt separerad från innehållet.
Det viktigaste att ta med sig: en sida vars data laddas via JavaScript har ofta ett JSON-API precis bakom sig. Data i mitt dynamiska test låg på en endpoint, och när jag pekade CheerioCrawler direkt mot det API:t fick jag tillbaka 8 av 8 produkter — utan webbläsare, på ungefär 0,035 sekunder. Samma data tog nästan fem sekunder att rendera via browser-spåret. Lärdomen är gammal men fortfarande sann: om du kan återskapa den underliggande requesten, gör det i stället för att starta Chromium. Crawlee låter dig göra det valet per crawler utan att byta ramverk.
Själva crawl-ramverket (det som gör att man väljer Crawlee framför ett rent webbläsarbibliotek)
Om allt du behövde var att rendera en sida, skulle du inte behöva Crawlee — då hade du använt Playwright eller Puppeteer på egen hand. Det ett rent webbläsarbibliotek inte ger dig är en crawl: kö, deduplicering, djupkontroll, retries. Det är den delen av Crawlee som inte handlar om motorer alls.
Jag körde en crawl inom samma domän från en fixturesrot med enqueueLinks och djupspårning. Crawlee gick igenom 11 sidor över djupen {0:1, 1:3, 2:7} — en rot, tre sidor ett hopp ut, sju sidor två hopp ut — och respekterade maxRequestsPerCrawl som stoppvillkor. RequestQueue skötte bokföringen. När jag riktade en request mot en sida som returnerade HTTP 500, försökte Crawlee igen och lät sedan felet gå vidare via sin failedRequestHandler i stället för att tyst svälja det eller krascha körningen.

Det här är det starkaste argumentet för Crawlee framför ett fristående webbläsarverktyg: crawl-orchestreringen är inbyggd, och viktigast av allt är den densamma oavsett om motorn under ytan är HTTP eller webbläsare. Du skriver din kö- och länkföljningslogik en gång. Separat avgör du om varje crawler ska rendera JavaScript.
Installation och den dolda webbläsarnedladdningen
Installationen var mestadels smärtfri, med en fälla som biter nya användare.
npm install crawlee playwright gick rent — 0 sårbarheter rapporterades. Men PlaywrightCrawler kommer inte att starta förrän du också kör npx playwright install chromium, vilket hämtar ner en Chromium-binär på ungefär 81,7 MiB. Att bara installera crawlee hämtar inte någon webbläsare. Om du hoppar över det steget och går direkt till en browser-crawler får du ett startfel som inte är självklart om du inte redan känner till Playwrights paketeringsmodell. Det är ärvt beteende från Playwright, inte en Crawlee-bugg, men det är en verklig friktion vid första körningen som är värd att nämna.

En operativ detalj till: som standard skriver Crawlee till en lokal storage/-katalog. Mitt testupplägg pekade om detta till en temporär skräpkatalog och stängde av persistens för att hålla det rent, men en vanlig körning lämnar en storage/-mapp i projektet. Inget problem, bara bra att känna till innan den dyker upp i git status.
En tredje motor, kort sagt
Crawlees parity-berättelse stannar inte vid Cheerio och Playwright. Det finns också PuppeteerCrawler, och jag kollade hur långt “samma gränssnitt” egentligen sträcker sig dit — på klass- och API-nivå, inte genom en live-crawl.
Alla tre crawler-klasser härstammar från samma BasicCrawler-bas. CheerioCrawler går via en HttpCrawler; PlaywrightCrawler och PuppeteerCrawler går båda via en delad BrowserCrawler. När jag inspekterade det installerade paketet var 24 publika metoder gemensamma för alla tre motorer, inklusive kö- och lagringsoperationerna som hela designen vilar på — run, addRequests, pushData, getData, getDataset, exportData, getRequestQueue, useState, stop. PuppeteerCrawler och PlaywrightCrawler exponerar faktiskt exakt samma publika metoduppsättning. De enda skillnaderna mellan motorerna ligger längs gränsen mellan HTTP och browser, vilket är precis där man förväntar sig dem.
Gränsen som är viktig att säga tydligt: jag körde inte en live-PuppeteerCrawler-crawl. Peer-dependencyn puppeteer är valfri och fanns inte i mitt testpaket, och att köra den skulle innebära ännu en webbläsarnedladdning. Så Puppeteer-pariteten här är verifierad strukturellt — samma basklass, samma delade metoder, samma form på handler-kontexten — inte genom en faktiskt körning. Och även när gränssnittet matchar är beteendet under huven inte identiskt: Crawlees egen vägledning påpekar att Playwright väntar automatiskt på element medan Puppeteer kräver att du väntar uttryckligen. Det är ett särdrag hos motorn, inte en Crawlee-brist, men det betyder att “samma API” inte är “samma kod inuti varje handler”.
Det jag inte testade
Här är det jag medvetet lät vara kvar till nästa omgång, så att du inte läser in mer i resultaten än de faktiskt visar.
- Skala. Allt kördes på små fixtures och korta publika crawls. Ingen långkörning på 100–1 000 sidor, så jag kan inte uttala mig om Crawlees autoskalning eller stabilitet under verklig belastning.
- Köpersistens och återupptagning. Jag dödade aldrig en crawl mitt i körningen för att se om
RequestQueuefortsätter snyggt efter en krasch. Det är en viktig funktion för långa jobb och är inte testad här. - Dataset- och KeyValueStore-export. Jag skrev mina JSON/CSV-exporter manuellt i testharnessen. Crawlees inbyggda exportflöden för
Dataset/KeyValueStore— kanske den största användarvänlighetsvinsten med ramverket — testade jag inte. - Proxy- och sessionpooler. Crawlee levererar proxyrotation och fingerprinting. Jag behandlar det strikt som en fråga om efterlevnad och drift, inte som ett “anti-bot bypass”-säljargument, och jag stresstestade det inte åt något håll.
Och tiderna genom hela texten kommer från en maskin och en körning. De visar formen på kostnaden mellan HTTP och webbläsare. De är inte benchmarks, och jag skulle inte citera dem som sådana.
För- och nackdelar
Fördelar
- Ett API-gränssnitt för både HTTP- och browser-crawling — motorbytet är verkligen ett klassbyte, verifierat med 0 → full data både på ett lokalt testfall och en publik sajt.
- Ett genuint crawl-ramverk:
RequestQueue,enqueueLinksmed djupkontroll, retries och enfailedRequestHandler, inte bara en sidrenderare. - Noggrann HTTP-extraktion (12/12 statiska, 3/3 artikelstycken, 8/8 via JSON-API) när JavaScript inte står i vägen.
- Browser-spåret kan hämta innehåll som HTTP-spåret fysiskt inte ser, och det kan ta skärmdumpar.
- Apache-2.0, TypeScript, aktivt underhållet.
Nackdelar
- Browser-crawlers kräver en separat
npx playwright install chromium(~81,7 MiB) somnpm install crawleeinte sköter — lätt att missa. - Browser-rendering har en verklig kostnad per sida (~5s mot under en sekund i mitt entest).
- Standardbeteendet lämnar en
storage/-katalog vid vanliga körningar. - Skala, köpersistens/återupptagning och exportflöden har inte bevisats i min testning.
- Proxy- och fingerprinting-funktioner måste användas inom sajtens villkor och lagen — ett ansvar, inte en funktion att luta sig mot.
När du ska välja Crawlee i stället för ett managed API
Crawlee är ett bygg-det-själv-verktyg, och det är rätt val för många team. Välj det när du vill äga crawlern i din egen Node-kodbas, blanda HTTP- och browser-crawling i samma projekt utan att byta ramverk, och själv kontrollera kö och lagring. Om du är bekväm med att köra och så småningom skala en browser-flotta ger Crawlee dig en ren och välgjord stomme att hänga det på.
Den andra vägen är att inte driva någon av den infrastrukturen själv. Om du inte vill lägga din utvecklingstid på att vakta Chromium-instanser, proxyrotation och anti-bot-hantering är ett managed API alternativet — och det är där vår egen utvecklarstack på Thunderbit passar in. För tekniska användare är Thunderbit inte Chrome-tillägget; det är ett AI-scraping API, MCP-server och CLI. Du anropar POST /distill för att göra en sida till ren, LLM-vänlig Markdown, eller POST /extract med ett JSON Schema för att få tillbaka strukturerad data, med renderMode satt till none, basic eller full så att du själv avgör när full webbläsarrendering är värd det. MCP-servern låter en AI-agent (Claude, Cursor och andra MCP-klienter) göra scraping mitt i ett arbetsflöde, och CLI:t körs från terminalen eller CI:
Testa Thunderbit för extrahering av webdata
npx -y @thunderbit/thunderbit-cli distill "<url>" -f markdown > out.md
Skillnaden som spelar roll för utvecklare: Crawlee ger dig råmaterialet — renderad HTML, parsade noder — och du äger pipelinen; ett managed API levererar färdig JSON som matchar schemat, med JS-rendering, CAPTCHAs och anti-bot-hantering skött på serversidan. Olika jobb. Om du vill ha maximal kontroll och inte har något emot drift, välj Crawlee. Om du vill ha datan utan browser-flottan, välj den hanterade vägen. Många team använder till slut båda: en för skräddarsydda crawls och en för fallen där man bara vill ha den strukturerade datan. Du kan se kostnadsavvägningen på Thunderbits prissättning.
Slutsats
Ska du använda Crawlee? Ja — om du är en Node- eller TypeScript-utvecklare som vill ha ett enda ramverk som täcker både HTTP- och browser-crawling med en riktig crawl-kö under huven. Löftet om två motorer är skälet att välja det, och det höll hela vägen i mina tester: samma URL gick från 0 till full data med ett klassbyte, den statiska extraktionen var korrekt och snabb, och crawlning med kö och djup fungerade som dokumenterat.
Gå in med två saker i bakhuvudet. Budgetera för den dolda webbläsarnedladdningen första gången du använder PlaywrightCrawler, och anta inte att de delar jag inte testade — skala, återupptagning efter krasch, inbyggda exporter — fungerar lika bra som de delar jag testade innan du har kört dem på din egen arbetslast. Som grund för att bygga din egen crawler är Crawlee en stark och välkonstruerad ingenjörslösning. Som färdig, helt hands-off datapipeline är det en startpunkt, inte slutmålet.
Testa Thunderbit för extrahering av webdata Get Started Free
Vanliga frågor
Är Crawlee gratis, och vilken licens har det?
Ja. Crawlee är öppen källkod under Apache-2.0-licensen och installeras från npm (npm install crawlee). Versionen jag testade var 3.17.0. För att köra browser-crawlers krävs en separat Chromium-nedladdning via Playwright, som också är gratis men lägger till cirka 81,7 MiB i din installation.
CheerioCrawler vs PlaywrightCrawler — vilken ska jag använda?
Använd CheerioCrawler när datan finns i den råa HTML:en eller i ett underliggande JSON-API — den är mycket snabbare och startar aldrig någon webbläsare. Använd PlaywrightCrawler när innehållet renderas av JavaScript, vilket märks när HTTP-spåret ger tomma resultat. I mina tester gav HTTP-motorn 0 poster på en JS-renderad sida medan browser-motorn gav allt. Eftersom de delar samma API är bytet ett klassbyte, inte en omskrivning.
Behöver Crawlee en webbläsare för att fungera?
Bara för browser-crawlers. CheerioCrawler behöver ingen webbläsare alls. PlaywrightCrawler (och PuppeteerCrawler) behöver en webbläsarbinär — installera den med npx playwright install chromium. Observera att npm install crawlee ensamt inte hämtar någon webbläsare, vilket är den vanligaste fällan vid första körningen.
Kan Crawlee hantera pagination och crawls över flera sidor?
Ja, och det är en av huvudorsakerna att välja det framför ett fristående webbläsarbibliotek. enqueueLinks följer länkar (inklusive pagination-selektorer som .next-page), RequestQueue deduplicerar och styr crawlen, och du får både djupkontroll och maxRequestsPerCrawl-begränsningar. I testet gick en crawl inom samma domän genom 11 sidor över djup 0–2, och misslyckade requests dök upp via en failedRequestHandler.
Hur står sig Crawlee mot ett hostat scraping-API?
Crawlee är självhostat: du bygger och kör crawlern själv och äger skalning, proxies och anti-bot-hantering. Ett managed API som Thunderbits distill/extract-ändpunkter levererar ren Markdown eller strukturerad JSON som matchar schema, med rendering och anti-bot skött på serversidan, exponerat via ett API, en MCP-server och en CLI. Välj Crawlee för maximal kontroll över din egen pipeline; välj ett managed API när du inte vill drifta och skala browser-infrastrukturen själv.


