สิ่งที่ทำให้ Crawlee น่าใช้ก็คือระบบจัดการการครอลของมันรองรับได้ทั้งการดึงข้อมูลผ่าน HTTP และการรันผ่านเบราว์เซอร์ ดังนั้น URL เดียวกันจึงให้ผลลัพธ์ต่างกันได้ ขึ้นอยู่กับ crawler ที่เลือกและเงื่อนไขความพร้อมของหน้า
บนหน้า Quotes to Scrape JS แบบสาธารณะ CheerioCrawler เจอโควตเป้าหมาย 0 รายการ ขณะที่ PlaywrightCrawler เจอ 10 รายการหลังรอ .quote ขั้นตอนครอลโดยรวมคล้ายกันก็จริง แต่กรณีนี้ไม่ใช่แค่สลับคลาสบรรทัดเดียวแล้วจบ: handler ของ Cheerio ใช้ $ ส่วน handler ของ Playwright ใช้ page มีการรอแบบชัดเจน และดึงข้อมูลฝั่งเบราว์เซอร์
Crawlee คืออะไรจริง ๆ
Crawlee (โปรเจกต์ apify/crawlee เวอร์ชัน 3.17.0) คือไลบรารีสำหรับ web scraping และ browser automation บน Node.js กับ TypeScript รองรับการครอลผ่าน HTTP โดยใช้ Cheerio หรือ JSDOM และรองรับการครอลผ่านเบราว์เซอร์ด้วย Playwright หรือ Puppeteer โปรเจกต์นี้ใช้สัญญาอนุญาต Apache-2.0 ดังนั้นถ้าจะนำไปแจกจ่ายต่อ ก็ควรเช็กเงื่อนไขการแจ้งเครดิตและข้อกำหนดให้ครบ
กรอบคิดสำคัญคือแยก “ดึงหน้าเว็บ” ออกจาก “อ่านข้อมูลจากหน้าเว็บ” เส้นทางหนึ่งดาวน์โหลด HTML ดิบและไม่รัน JavaScript อีกเส้นทางหนึ่งเปิด Chromium และรันสคริปต์ของหน้าได้ แต่ก็ยังต้องมีเงื่อนไขความพร้อมที่เหมาะสม และอาจพลาดเนื้อหาที่ต้องโต้ตอบ เนื้อหาที่โหลดแบบ lazy-load, shadow DOM, การเรียก API ล้มเหลว หรือเนื้อหาที่ถูกบล็อกโดย bot Crawlee จึงแสดงแนวคิดของ lifecycle ที่สอดคล้องกันในแต่ละเส้นทาง แทนที่จะเป็น DOM primitive ที่ใช้แทนกันได้
นี่คือประเด็นที่ควรเข้าใจก่อนเขียน selector ตัวแรก เพราะการเลือก engine ระหว่างสองแบบนี้จะเป็นตัวตัดสินเลยว่า scraper ของคุณจะได้ข้อมูลกลับมาหรือเจอแค่ความว่างเปล่าบนเว็บนั้น
ฟีเจอร์หลัก: สอง engine, API เดียวกัน

CheerioCrawler ดึง HTML แล้ว parse ด้วย Cheerio ส่วน PlaywrightCrawler ควบคุม Chromium และถ่ายภาพหน้าจอได้ ทั้งสองแบบใช้ requestHandler, มี run(), และแชร์แนวคิดการครอลอย่าง queue และการค้นหาลิงก์เหมือนกัน แต่ context ของ handler ต่างกัน: เส้นทาง Cheerio ที่ทดสอบใช้ $ ในการดึงข้อมูล ขณะที่ฝั่งเบราว์เซอร์ใช้ page, waitForSelector, และ $$eval โครงสร้าง queue และ lifecycle อาจคงเดิมได้ แต่โค้ดสำหรับ extraction อาจต้องมี adapter หรือเขียนใหม่
เบื้องหลังนั้น Crawlee ยังให้โครงสร้างพื้นฐานที่การครอลจริงต้องมี RequestQueue ใช้จัดการ frontier ของ URL ที่จะเข้าไปเยี่ยม, deduplicate และติดตามว่ายังทำอะไรไปแล้วบ้าง enqueueLinks ใช้ค้นหาและเพิ่ม URL ใหม่เข้า queue (พร้อมตัวกรอง selector และ same-hostname) เพื่อให้การครอลแตกแขนงต่อได้เอง Dataset ใช้เก็บข้อมูลที่ดึงมาเพื่อส่งออก ตามค่าเริ่มต้น Crawlee จะเก็บทั้งหมดนี้ลงในโฟลเดอร์ storage/ บนดิสก์ ซึ่งสะดวกเวลาจะ resume แต่ก็อาจชวนงงนิดหน่อยตอนเจอโฟลเดอร์ storage/ โผล่มาในโปรเจกต์โดยไม่ได้ตั้งใจ (ในชุดทดสอบนี้ผมเปลี่ยนเส้นทางให้ไปใช้ temp dir และปิด persistence เพื่อให้การทดสอบสะอาด)
แต่ละชิ้นส่วนดูไม่หวือหวาในตัวเอง จุดสำคัญคือมันถูกแชร์ร่วมกันระหว่างสอง engine ดังนั้น queue, link discovery และ dataset จะทำงานเหมือนกันไม่ว่าคุณจะครอลผ่าน HTTP หรือผ่านเบราว์เซอร์ คุณเรียนรู้ API เดียว แต่ได้กลยุทธ์การดึงข้อมูลสองแบบ
การติดตั้ง: เบราว์เซอร์ต้องลงแยก
การติดตั้งในสภาพแวดล้อมที่ทดสอบไม่ได้มี Chromium executable ติดมาให้หลังติดตั้งแพ็กเกจ

npm install crawlee playwright ติดตั้งได้เรียบร้อยสำหรับผม — 85 packages, ไม่มีช่องโหว่, ไม่มีปัญหาอะไร ถ้าหยุดแค่นี้แล้วรัน CheerioCrawler ทุกอย่างจะทำงาน เพราะการครอลผ่าน HTTP ไม่ต้องใช้เบราว์เซอร์
แต่ในสภาพแวดล้อมนี้ Chromium ต้องติดตั้งเพิ่มด้วย npx playwright install chromium; ถ้าไม่ทำ PlaywrightCrawler จะเริ่มทำงานไม่ได้ payload ของเบราว์เซอร์ที่เห็นมีขนาดราว 82 MiB แต่บันทึกต้นฉบับไม่ได้ระบุว่าตัวเลขนั้นเป็นขนาดโอนย้ายหรือขนาดบนดิสก์ นี่เป็นข้อสังเกตจากเครื่องทดสอบ ไม่ใช่คุณสมบัติตายตัวของผลิตภัณฑ์ เส้นทางเอกสารและพฤติกรรมของแพ็กเกจอาจเปลี่ยนได้ ดังนั้นบทความนี้ไม่ได้อ้างว่าการขาดขั้นตอนดังกล่าวเกิดกับทุกกรณีหรือไม่มีการระบุไว้ถาวร
ให้วางแผนการติดตั้งที่ทดสอบไว้เป็น 2 ขั้น: ลง Node packages ก่อน แล้วค่อยลง browser ที่ Playwright path ใช้งาน ตรวจสอบคำแนะนำการตั้งค่า Crawlee และ Playwright เวอร์ชันล่าสุดให้ตรงกับแพลตฟอร์มที่คุณจะ deploy
ทดลองใช้งานจริง: หน้าเดียวกัน แต่ได้คำตอบคนละแบบ

การทดสอบหลักส่ง fixture ที่เรนเดอร์ด้วย JavaScript ชุดเดียวกันให้ crawler ทั้งสองตัว URL และฟิลด์เป้าหมายเหมือนกัน แต่ primitive สำหรับ extraction ต่างกัน
บน fixture ภายในเครื่อง CheerioCrawler คืนค่าการ์ดเป้าหมาย 0 ใบ เพราะมันไม่มีอยู่ใน HTML ดิบ PlaywrightCrawler รอ #dynamic-products article.product-card ก่อน แล้วจึงคืนการ์ดที่คาดไว้ครบ 8 ใบและจับภาพหน้าจอได้ ผลลัพธ์นี้ยืนยันความครบถ้วนระดับ fixture สำหรับฟิลด์ที่เลือกหลังรอเงื่อนไขนั้น ไม่ได้แปลว่าเบราว์เซอร์จะเห็นทุกสถานะของทุกหน้าเสมอไป ไฟล์ต้นฉบับและ screenshot อยู่ใน repo benchmark

บนหน้า Quotes to Scrape JS แบบสาธารณะ CheerioCrawler พบโควตเป้าหมาย 0 รายการ ส่วน PlaywrightCrawler รอ .quote ก่อนดึงข้อมูล จึงได้ 10 รายการ การทดสอบนี้ยืนยันเส้นแบ่งเดียวกันระหว่าง HTTP กับเบราว์เซอร์บน target สาธารณะ โดยที่ class ของ crawler, context ของ handler, เงื่อนไขการรอ และ primitive สำหรับ extraction ต่างกันทั้งหมด
ข้อสรุปที่ได้จึงแคบลงและชัดขึ้น: ให้ตรวจฟิลด์ที่จำเป็นหลังเส้นทาง HTTP ก่อน และค่อยยกระดับไปใช้ browser crawler เมื่อ response ดิบไม่มีข้อมูลนั้น Handler ฝั่งเบราว์เซอร์ก็ต้องรอเงื่อนไขที่ผูกกับฟิลด์เหล่านั้นด้วย
เส้นทาง HTTP สามารถดึงเรคคอร์ดที่คาดไว้ครบจาก static catalog และ article fixtures, ถอดข้อมูล item ทั้ง 8 จาก JSON response โดยตรง, เดิน graph ที่มีขอบเขต 11 หน้า, และส่ง response 500 ไปยัง failedRequestHandler ได้สำเร็จ ทั้งหมดนี้เป็นการเช็กความสามารถคนละด้าน ไม่ใช่คะแนนความแม่นยำก้อนเดียว ส่วนบนหน้า Books to Scrape แบบสาธารณะ selector ที่ตั้งไว้ดึงสินค้าได้ 20 รายการ ถือเป็น smoke test
| การทดสอบ | Engine | ผลลัพธ์ |
|---|---|---|
| Static extraction: catalog + pagination | CheerioCrawler | ได้สินค้าตามคาด 12/12 รายการ |
| Article extraction | CheerioCrawler | title + ย่อหน้า 3/3 |
| Transport: direct JSON response | CheerioCrawler | ได้สินค้าตามคาด 8/8 รายการ |
| Traversal: internal-link graph | CheerioCrawler | 11 หน้า, ความลึก {0:1, 1:3, 2:7} |
| Failure routing: HTTP 500 | CheerioCrawler | สถานะถูกส่งไปยัง failure handler |
| Rendering: local fixture | CheerioCrawler | การ์ดเป้าหมาย 0 ใบใน HTML ดิบ |
| Rendering: local fixture | PlaywrightCrawler | ได้ครบ 8/8 หลังรอ target-selector |
| Rendering: Quotes JS | CheerioCrawler | โควตเป้าหมาย 0 รายการใน HTML ดิบ |
| Rendering: Quotes JS | PlaywrightCrawler | ได้ 10 หลังรอ target-selector |
เวลารันเต็มและตัวเลขรายทดสอบดูได้ใน results/crawlee-test-summary.json
ต่อไปคือข้อควรระวังแบบตรงไปตรงมา เพราะการทดสอบครั้งเดียวบนเครื่องเดียวมีข้อจำกัด และผมไม่อยากทำเหมือนมองไม่เห็นมัน นี่คือ timing ไม่ใช่ benchmark — เครื่องเดียว รันครั้งเดียว ดังนั้นให้มองต้นทุนต่อหน้าของฝั่งเบราว์เซอร์ว่า “ช้ากว่า Cheerio ที่ทำงานระดับ sub-second อย่างมีนัยสำคัญ” ไม่ใช่ตัวเลขที่อ้างอิงได้สากล และยังมีหลายอย่างที่ไม่ได้ทดสอบในรอบนี้: proxy rotation, session pool, งานขนาดใหญ่ระดับหลายร้อยถึงหลายพันหน้า, RequestQueue persistence และการ resume หลัง crash, engine ของ Puppeteer, และ ergonomics ของการ export จาก Dataset/KeyValueStore (ผมเขียน export เองในรอบนี้) ผมยืนยันเรื่องโครงสร้างสอง engine และความแม่นยำระดับ fixture ได้ แต่ยังยืนยันเรื่องสเกลหรือการรับมือการบล็อกไม่ได้ ดังนั้นจะไม่อ้าง
อะไรที่แชร์กันได้ และอะไรที่ต้องเปลี่ยน

สิ่งที่เหมือนกันคือชั้น orchestrate การครอล ทั้ง crawler ทั้งสองคลาสรับ requestHandler และมี run() เหมือนกัน queue, metadata ของ request, การค้นหาลิงก์, failure hooks และแนวคิดเรื่อง storage สามารถจัดวางให้สอดคล้องกันได้ทั้งสองเส้นทาง ทำให้ทีมไม่ต้องเรียนรู้ infrastructure ใหม่ทั้งหมดทุกครั้งที่ target ใด target หนึ่งต้องใช้เบราว์เซอร์
แต่ชั้นที่เข้าถึงหน้านั้นไม่เหมือนกัน CheerioCrawler handler รับการเข้าถึงแบบ Cheerio เช่น $ และทำงานกับ response body ได้โดยไม่ต้องมีเบราว์เซอร์ ส่วน PlaywrightCrawler handler ที่ทดสอบรับ page; มันรอ selector และประเมินผลบน browser DOM ถึงแม้ทั้งสอง handler จะปล่อย schema ของ record เหมือนกัน แต่ก็ไปถึงข้อมูลนั้นผ่าน API คนละชุด อาจมี adapter ช่วยซ่อนความต่างบางส่วนได้ แต่ชุดทดสอบนี้ไม่ได้สร้างหรือสาธิตไว้
ความต่างนี้สำคัญต่อการประเมินงาน เพราะการเปลี่ยน crawler class อาจคง queue, dataset และนโยบาย URL ไว้ได้ แต่ selectors, readiness checks, screenshots, ขั้นตอนโต้ตอบ และ error handling ก็ยังเปลี่ยนได้อยู่ บทความนี้จึงถือว่า “shared crawl plumbing” คือประโยชน์ที่พิสูจน์ได้ และไม่รับ “ย้ายได้ในบรรทัดเดียว” เป็นคำสัญญาที่รองรับไม่ได้
แนวทางเลือก engine แบบใช้งานจริง
เริ่มจากเส้นทาง HTTP ก่อนเมื่อ HTML ที่ส่งกลับมา หรือ JSON response โดยตรง มีฟิลด์ที่ต้องการครบ กำหนดสัญญาเรื่องความครบถ้วนไว้ชัดเจน—เช่น required keys, จำนวน item ขั้นต่ำ หรือ target selector—แล้วให้ fail อย่างชัดเจนเมื่อไม่ผ่าน อย่ามอง array ว่างว่าแปลว่าไม่มีข้อมูลเสมอไป ในสองกรณี JavaScript ที่ทดสอบนี้ มันหมายถึง representation ที่เลือกมานั้นไม่มี element เป้าหมาย
| เงื่อนไขของ target | เริ่มด้วย | ยกระดับเมื่อ |
|---|---|---|
| ฟิลด์ที่ต้องการอยู่ใน HTML ที่ส่งกลับมา | CheerioCrawler | selector หรือฟิลด์ที่จำเป็นไม่ปรากฏ |
| ข้อมูลอยู่ใน JSON response ที่เรียกได้ตรง ๆ | CheerioCrawler | request ต้องพึ่ง state ที่มีได้เฉพาะในเบราว์เซอร์ |
| หน้าเว็บใส่ element เป้าหมายหลังรันเสร็จ | PlaywrightCrawler | ไม่เกี่ยว; ให้กำหนด readiness check เฉพาะ target |
| ยังไม่รู้ว่า target เป็นแบบไหน | เริ่มจาก HTTP พร้อม validation ความครบถ้วน | validation ล้มเหลวด้วยผลลัพธ์แบบ typed “representation incomplete” |
เมื่อจำเป็นต้องใช้ execution จริง ให้ส่ง typed failure นั้นต่อไปยัง browser handler ในชุดทดสอบนี้ หน้า local รอ #dynamic-products article.product-card ส่วนหน้า quotes สาธารณะรอ .quote เงื่อนไขเหล่านี้คือส่วนหนึ่งของสัญญาการดึงข้อมูล การอ้างอิงเพียง event โหลดหน้าแบบทั่วไปไม่ได้พิสูจน์ว่าข้อมูลแอปฯ มาถึงแล้ว และการทดสอบนี้ก็ไม่สนับสนุนกฎการรอแบบสากล
หลังยกระดับแล้ว ให้รักษา schema ของ output ให้คงเดิมแม้ DOM primitive จะต่างกัน บันทึกว่า engine ใดเป็นผู้สร้างผลลัพธ์, readiness condition ใดผ่าน, และการตรวจสอบฟิลด์ที่จำเป็นสำเร็จหรือไม่ วิธีนี้จะทำให้ fallback จาก HTTP ไป browser มองเห็นได้ แทนที่จะปล่อยให้ฟิลด์ที่หายไปกลายเป็นเรคคอร์ดที่ถูกยอมรับแบบเงียบ ๆ
สุดท้าย ให้ถือว่าการติดตั้งเบราว์เซอร์และต้นทุนการใช้งานเป็น input ของ deployment ตัวเลขราว 82 MiB มีประโยชน์แค่เป็นลำดับขนาดในเครื่องทดสอบเท่านั้น คุณควรวัด build ของเบราว์เซอร์, platform, พฤติกรรม cache และผลกระทบต่อ image ในสภาพแวดล้อมของคุณเอง ส่วน proxy rotation, sessions, persistence, crash recovery และ concurrency ต่อเนื่อง ยังต้องมีการทดสอบของตัวเองก่อนที่จะนำ fixture ชุดนี้ไปตัดสินใจระดับ production
ข้อดีและข้อเสีย
ข้อดี:
- HTTP crawler และ browser crawler แชร์แนวคิด lifecycle ร่วมกัน แต่ยังแยก context การ extraction ตาม engine ได้ชัดเจน
- การดึงข้อมูลผ่าน HTTP ทำได้แม่นยำระดับ 1.0 บน static catalog, article และ JSON API
- โครงสร้างพื้นฐานที่แชร์กันระหว่างสอง engine:
RequestQueue,enqueueLinksพร้อมควบคุม depth,Dataset - ฝั่งเบราว์เซอร์รันสคริปต์ของ fixture และกู้คืนรายการเป้าหมายที่คาดไว้ครบในสองการทดสอบแบบ JavaScript-rendered
- การจัดการความล้มเหลวทำได้เรียบร้อย — HTTP 500 ถูกส่งออกมาโดยไม่ทำให้โปรแกรมล้ม
- ใช้สัญญาอนุญาต Apache-2.0; ผู้ใช้งานต่อควรตรวจสอบข้อกำหนดการแจ้งและให้เครดิต
ข้อเสีย:
- ในสภาพแวดล้อมที่ทดสอบ ต้องติดตั้ง Chromium แยก หากไม่มี
PlaywrightCrawlerจะไม่เริ่มทำงาน - ฝั่ง HTTP ไม่สามารถดึง target elements ที่ไม่มีอยู่ใน HTML ดิบได้ ถ้าไม่ตรวจความครบถ้วนก่อน อาจดูเหมือนผลลัพธ์ว่างที่ถูกต้อง
- ฝั่งเบราว์เซอร์ต้องแบกรับ binary ของ browser เพิ่ม และมีต้นทุนต่อหน้าสูงกว่าในการทดสอบครั้งนี้; ขนาดและเวลาแตกต่างได้ตาม build และ platform
- การรันค่าเริ่มต้นจะทิ้งโฟลเดอร์
storage/ไว้บนดิสก์ - รองรับเฉพาะ Node/TypeScript — ถ้าใช้ Python ก็ไม่ตรง
เหมาะกับใคร — และใครควรข้าม
Crawlee เหมาะกับทีม Node หรือ TypeScript ที่ต้องการทั้งการครอลแบบ HTTP และแบบเบราว์เซอร์ภายใต้แนวคิด queue และ lifecycle เดียวกัน แนวทางที่ใช้งานได้จริงคือพยายามใช้ HTTP crawler ก่อน ตรวจฟิลด์ที่จำเป็น แล้วค่อยส่ง typed completeness failure ไปยัง browser handler พร้อม readiness condition ที่เฉพาะกับ target โค้ด DOM access ของ handler จะต่างกันตาม engine แม้ว่า queue และ link-discovery plumbing จะใช้ร่วมกันได้
ถ้าคุณเป็นทีม Python ให้ตั้งความคาดหวังใหม่หรือมองตัวเลือกอื่น (Crawlee เป็น Node/TS — มีพอร์ต Python แยกต่างหาก แต่แพ็กนี้ทดสอบไลบรารี Node), ถ้าเป้าหมายทั้งหมดเป็น static และคุณอยากได้ HTTP scraper แบบเบาและเฉพาะงานเดียว หรือถ้าคุณต้องการผลลัพธ์ที่พิสูจน์แล้วในระดับสเกล — proxy rotation, session pools, resume-after-crash — ซึ่งการลงมือทดสอบนี้ไม่ได้ครอบคลุม และถ้าคุณจะใช้ PlaywrightCrawler ก็ต้องติดตั้ง Chromium ก่อน ไม่เช่นนั้นมันจะไม่รัน
ทางเลือกอื่น รวมถึง Thunderbit อยู่ตรงไหน
Crawlee เป็นซอฟต์แวร์โอเพนซอร์สที่คุณติดตั้งและดูแลเอง ไม่มีค่าบริการรายครั้งจากผู้ให้บริการ แต่ต้นทุนฝั่ง browser compute, bandwidth, proxies, storage, observability และงานวิศวกรรมยังคงเป็นค่าใช้จ่ายในการดำเนินงาน คุณเป็นคนรับผิดชอบการเลือก crawler, browser binary, state ของ storage และ logic สำหรับ readiness เอง
รีวิวที่เกี่ยวข้อง: scrapy-playwright review
บริการ extraction แบบ managed จะย้ายภาระด้านการดึงข้อมูลและการกำหนด schema ไปให้ผู้ให้บริการ เราสร้าง Thunderbit ขึ้นมา แต่ไม่ได้รันกับ fixture ชุดนี้ ดังนั้นบทความนี้จึงไม่ใช้เพื่อเปรียบเทียบคุณภาพ latency ความเท่าเทียมของฟีเจอร์ หรือราคา สิ่งที่ต้องตัดสินคือทีมของคุณอยากได้การควบคุมภายใน process แบบ Crawlee หรือ boundary ของบริการแบบคิดตามครั้ง
รีวิว benchmark ที่เกี่ยวข้อง: บทเปรียบเทียบ scraper โอเพนซอร์สฉบับเต็ม, Playwright vs Puppeteer บนหน้าเดียวกัน, และ รีวิว Scrapy แบบไม่ใช้เบราว์เซอร์และ replay request
ลองใช้ Thunderbit เพื่อดึงข้อมูลเว็บ
บทสรุป
Crawlee เป็นตัวเลือกที่แข็งแรงสำหรับทีม Node หรือ TypeScript ที่ต้องการ orchestration การครอลร่วมกันทั้งแบบ HTTP และแบบเบราว์เซอร์ Handler ที่ทดสอบไม่ได้ใช้แทนกันได้: การย้ายไป Playwright ต้องใช้ page, ต้องมีการรอ target-selector และต้องดึงข้อมูลฝั่งเบราว์เซอร์ Proxy, session, persistence, resume และพฤติกรรมระดับสเกลใหญ่ยังเป็นคำถามที่ต้องทดสอบต่อ
ลองใช้ Thunderbit เพื่อดึงข้อมูลเว็บ Get Started Free
คำถามที่พบบ่อย
ความต่างจริง ๆ ระหว่าง crawler ทั้งสองแบบของ Crawlee คืออะไร?
CheerioCrawler ดึง HTML ผ่าน HTTP และไม่รัน JavaScript ส่วน PlaywrightCrawler ควบคุม Chromium และสามารถรันสคริปต์ของหน้า รวมถึงถ่ายภาพหน้าจอได้ แต่ต้องแลกด้วยต้นทุนต่อหน้าที่สูงกว่า ทั้งสองแบบแชร์แนวคิด lifecycle ร่วมกัน แต่ context ของ handler ไม่เหมือนกัน: ชุดทดสอบนี้ใช้ $ บนเส้นทาง HTTP และใช้ page, การรอ target-selector และการประเมินผลฝั่งเบราว์เซอร์บนเส้นทาง Playwright
ทำไม PlaywrightCrawler ถึงไม่รันหลังจากติดตั้ง Crawlee แล้ว?
ในสภาพแวดล้อมที่ทดสอบ การติดตั้งแพ็กเกจไม่ได้ให้ browser executable มาด้วย การติดตั้ง Chromium ด้วย npx playwright install chromium แก้ปัญหา launch ไม่ได้ ขนาดที่สังเกตได้ราว 82 MiB แต่บันทึกเดิมไม่ได้แยกว่าคือขนาดโอนย้ายหรือขนาดบนดิสก์ ดังนั้นควรวัดใหม่ตามแพลตฟอร์มและ build ของคุณ
CheerioCrawler ครอลหน้าเว็บที่เรนเดอร์ด้วย JavaScript ได้ไหม?
ไม่ได้รัน JavaScript ของหน้า แต่ยังสามารถเรียก JSON endpoint ที่ฝั่ง client ใช้ได้ ถ้าข้อมูลที่ต้องการมีเฉพาะหลังการรันเบราว์เซอร์ ให้ใช้ browser crawler และตั้ง readiness condition ให้ผูกกับฟิลด์เหล่านั้น
Crawlee แม่นยำสำหรับการดึงข้อมูล static ทั่วไปไหม? บน fixture ที่ควบคุมไว้ handler สามารถดึงสินค้า catalog ได้ 12/12 รายการ, ย่อหน้า article ได้ 3/3 ย่อหน้า, และรายการจาก direct JSON ได้ 8/8 รายการ นี่คือการตรวจความครบถ้วนระดับ fixture ไม่ใช่คะแนนความแม่นยำทั่วไปสำหรับเว็บไซต์ที่ยังไม่ได้ทดสอบ
Crawlee ใช้ฟรีในเชิงพาณิชย์ไหม? เผยแพร่ภายใต้ Apache-2.0 ตรวจสอบ license ปัจจุบันได้ใน repository และทบทวนข้อกำหนดการแจ้งและให้เครดิตสำหรับการนำไปแจกจ่ายต่อ
ก่อนนำไปใช้จริง ควรทดสอบส่วนที่ fixture นี้ยังไม่ครอบคลุม: concurrency ซ้ำ ๆ บนหน้าตัวแทน, พฤติกรรมของ proxy และ session, การกู้คืน queue แบบ persistent หลังถูกขัดจังหวะ, การล้าง browser process, และการ export dataset เมื่อเกิดความล้มเหลว เก็บเวอร์ชันของ browser และเส้นทางติดตั้งไว้พร้อมผลทดสอบเหล่านั้น crawler ทั้งสองคลาสช่วยลดความต่างของ orchestration แต่ไม่ได้ลบความจำเป็นของ readiness check เฉพาะ engine, งบทรัพยากร และการจัดการความล้มเหลวเชิงปฏิบัติการ


