Scrapy มักถูกมองว่าเป็นเครื่องมือที่ “เอาเว็บไซต์ยุคใหม่ไม่อยู่” เพราะมันไม่รัน JavaScript แต่ภาพนั้นกลับตาลปัตรสิ้นเชิง ความจริงคือการไม่เรนเดอร์หน้าเว็บนั่นแหละคือแนวคิดหลักของมัน และพอเห็นมันทำงานจริง คุณจะไม่มองว่านี่คือฟีเจอร์ที่ขาดอีกต่อไป
ผมพิสูจน์เรื่องนี้กับตัวเองในรอบเดียว โดยสร้างหน้าแคตตาล็อกที่เรนเดอร์ด้วย JavaScript ขึ้นมา จากนั้นให้ Scrapy เข้าไปยังหน้าที่เบราว์เซอร์จะเห็น ผลลัพธ์ที่ดึงกลับมาคือการ์ดสินค้า 0 ใบ จากนั้นผมหันสไปเดอร์ตัวเดิมไปยิงที่ endpoint แบบ JSON ที่หน้าเว็บนั้นเรียกอยู่เงียบ ๆ เบื้องหลัง และได้ข้อมูลครบ 8/8 รายการแบบสะอาด ๆ เครื่องมือเดียว เซสชันเดียว แต่ผลลัพธ์ตรงข้ามกันสุดขั้ว — และช่องว่างระหว่างตัวเลขสองชุดนี้แหละคือแก่นของรีวิวนี้
Scrapy คืออะไรจริง ๆ (และไม่ใช่อะไร)

Scrapy คือเฟรมเวิร์ก Python สำหรับไล่เก็บข้อมูลจากเว็บไซต์และดึงข้อมูลออกมาเป็นโครงสร้างชัดเจน นี่คือคำอธิบายตามที่ผู้ดูแลโปรเจกต์สรุปไว้ใน เอกสารภาพรวม และหลังจากใช้งานจริง ผมว่ามันตรงมาก — ไม่ต้องแต่งเติมให้ดูเว่อร์เกินจริงเลย Scrapy มีอายุและความน่าเชื่อถือมากพอที่จะเป็นคำตอบอัตโนมัติของนักพัฒนา Python เวลาถามว่า “ถ้าจะทำงานจริงจัง คนเขาใช้ตัวไหนกัน” และตัวเลขใน repo ก็ยืนยันได้: ประมาณ 62,981 GitHub stars ณ วันที่ 2026-07-07 (scrapy/scrapy) พร้อม 11,773 forks และ 590 issues ที่ยังเปิดอยู่ในวันเดียวกัน ใบอนุญาตเป็น BSD-3-Clause, รองรับ Python 3.10 ขึ้นไป และเวอร์ชันที่ผมทดสอบคือ 2.17.0 ซึ่งเพิ่งปล่อยเช้าวันที่ผมเริ่มทดสอบพอดี ดังนั้นรีวิวนี้ไม่มีเครื่องหมายดอกจันเรื่องเวอร์ชันเก่าติดท้าย
เส้นแบ่งที่ทำให้มันต่างจากกลุ่ม AI crawler รุ่นใหม่มีอยู่ชัดเจน: Scrapy เป็น HTTP-only โดยค่าเริ่มต้น ไม่มีเบราว์เซอร์ ไม่มี rendering engine มันดึง HTML ผ่านเครือข่าย ส่งให้ parser แล้วค่อยให้คุณคัดฟิลด์ออกมาด้วย CSS selector หรือ XPath ถ้าจะเรียกว่านี่เป็นข้อจำกัดก็พอพูดได้ครึ่งหนึ่ง แต่ก็ยังมองไม่เห็นเจตนาการออกแบบทั้งหมด แก่นของ Scrapy คือการบอกว่า การเปิด headless Chrome เพื่อไล่เก็บข้อมูลงานประจำมักไม่ใช่ทางที่ฉลาด ทางที่ดีกว่าคือหาคำขอข้อมูลที่หน้าเว็บนั้นเรียกอยู่แล้ว แล้วไปยิงตรงนั้นเลย
นี่ไม่ใช่แค่ผมตีความเอาเอง เอกสารอย่างเป็นทางการเรื่อง dynamic content ระบุชัดว่า ให้พยายามหาและจำลอง data request ต้นทางก่อน และค่อยใช้ headless browser เป็นทางเลือกสุดท้ายเมื่อจำลอง request นั้นไม่ได้จริง ๆ เครื่องมือเก็บข้อมูลจำนวนมากเปิดเบราว์เซอร์ก่อน แล้วไม่เคยคิดถึง API เลย แต่ Scrapy พลิกค่าเริ่มต้นนั้น
ฟีเจอร์หลัก และเหตุผลเชิงดีไซน์เบื้องหลังแต่ละอย่าง
ภายใน Scrapy มีชุดองค์ประกอบที่ออกแบบมาจากสมมติฐานเดียวกัน: คุณคือดีเวลอปเปอร์ที่ต้องการควบคุมเอง ไม่ใช่คนที่กดปุ่มเดียวแล้วให้วิซาร์ดทำทุกอย่าง
Spiders. คุณเขียนคลาส กำหนด start URLs แล้วสร้าง parse callback เพื่อคืน items หรือไล่ตามลิงก์ต่อ นี่ใช้โค้ดมากกว่า no-code extractor แต่แลกกับการที่คุณกำหนดได้ละเอียดเป๊ะว่าต้องเก็บอะไร และควรไหลไปหน้าไหนต่อ
Selectors. การ parse อาศัย parsel ซึ่งอยู่บน lxml อีกชั้น ทำให้ทั้ง CSS และ XPath เป็นตัวเลือกหลัก ไม่ใช่ของแถม ฟีเจอร์ที่ขับด้วย lxml นี่แหละที่ทำให้การเลือกข้อมูลรวดเร็ว และโค้ด extraction อ่านออกว่า “ตั้งใจทำอะไร” มากกว่าเป็นกอง string-slicing ที่พันกันยุ่งเหยิง
Feed exports. ถ้าชี้สไปเดอร์ไปที่ไฟล์ Scrapy จะ serialize items ออกเป็น JSON, JSON Lines, CSV หรือ XML ให้เลย โดยไม่ต้องเขียน plumbing เพิ่ม ในการทดสอบของผม สไปเดอร์ที่เก็บแคตตาล็อกแบบสแตติกตัวหนึ่งปล่อยทั้ง JSON และ CSV ออกมาได้โดยผมไม่ต้องเขียนโค้ด export สักบรรทัด เรื่อง feed export ใช้งานได้จริงตามที่บอกไว้
AutoThrottle และตัวควบคุมการ crawl. คำขอถูกจัดคิวแบบ asynchronous บน Twisted และคุณจะได้ทั้งการจำกัด concurrency, download delay, depth restriction, AutoThrottle สำหรับปรับ rate limit อัตโนมัติ และการเคารพ robots.txt เครื่องมือควบคุมเหล่านี้คือสิ่งที่ช่วยไม่ให้ crawl ขนาดใหญ่กลายเป็นการยิงถล่มเซิร์ฟเวอร์
HTTP-only ในฐานะฟีเจอร์อีกมุมหนึ่ง. ไม่มีเบราว์เซอร์จึงกินแรมน้อย ทำงานได้เร็ว และไม่ต้องเลี้ยงดู rendering engine ให้เปลืองทรัพยากร — ตราบใดที่ข้อมูลที่ต้องการเข้าถึงได้ผ่าน HTTP ปกติ ซึ่งในหลายกรณีกลับพบได้บ่อยกว่าที่สาย browser-first คิด
การติดตั้ง: สแตกของ dependency ที่ไม่มีใครอยากถ่ายรูปโชว์

การติดตั้งไม่มีดราม่า ซึ่งสำหรับเฟรมเวิร์กขนาดนี้ถือว่าสมควรพูดให้ชัด pip install Scrapy==2.17.0 จบอย่างเรียบร้อยใน virtual environment ใหม่บน macOS arm64 โดยดึง binary wheel มาใช้ ไม่ต้องคอมไพล์อะไรจนชนกำแพง ไม่มีเหตุการณ์ใหญ่ให้เล่า — และนั่นแหละคือประเด็น
แต่ถ้ามองลงไปในสิ่งที่ถูกดึงเข้ามา scrapy version -v รายงานว่า Scrapy 2.17.0 ทำงานอยู่บน lxml 6.1.1, Twisted 26.4.0, pyOpenSSL 26.3.0 และ cryptography 49.0.0 โดยมี parsel, cssselect และ tldextract มาช่วยเติมเต็ม นี่คือ footprint ของเฟรมเวิร์กจริง ๆ ไม่ใช่ parser HTML ไฟล์เดียว บนเครื่องนี้มี wheel ครบทุกตัว ทำให้การติดตั้งราบรื่น แต่บนสภาพแวดล้อมอื่น เอกสารทางการยังเตือนเรื่อง dependency ที่อาจสะดุดตามแพลตฟอร์มอยู่ และในอดีตจุดที่มักมีปัญหาคือฝั่ง cryptography กับ Twisted ดังนั้นถ้าคุณใช้เครื่องแปลก ๆ ก็ควรเผื่อเวลาไว้บ้าง การติดตั้งราบรื่นในเคสนี้จริง แต่ขนาดของสิ่งที่ถูกติดตั้งก็ยังเป็นข้อมูลสำคัญก่อนตัดสินใจ เพราะคุณกำลังเอาเฟรมเวิร์กเข้ามาทั้งชุด และมันก็หนักสมชื่อเฟรมเวิร์ก
ทดลองใช้งานจริง: อะไรผ่าน อะไรไม่ผ่าน

พอติดตั้งเสร็จ เส้นทางแบบ static ก็ผ่านฉลุย เก็บได้ครบ ไม่มีข้อมูลหลุด
| การทดสอบ | ผลลัพธ์ | เวลา |
|---|---|---|
| แคตตาล็อก static ในเครื่อง + pagination | สินค้า 12/12 รายการ | 0.557s |
| ส่งออก CSV ของแคตตาล็อก static | เขียนได้ 12 แถว | (รันเดียวกัน) |
| ดึงบทความ | title + 3/3 ย่อหน้าหลัก | 0.416s |
| crawl graph, DEPTH_LIMIT=2 | 11 หน้า ครอบคลุม depth 0/1/2 | 0.904s |
| หน้า local 500 | จับสถานะ 500 ได้ ไม่มีล่ม | 0.424s |
| Books to Scrape (สาธารณะ) | สินค้า 20 รายการ | 2.053s |
| Quotes to Scrape spider (สาธารณะ) | 12 รายการคำคม | 3.465s |
สไปเดอร์ที่เก็บแคตตาล็อกแบบ static ไล่ pagination จากหน้าแรกไปหน้าสองและเก็บข้อมูลได้ 12/12 รายการที่คาดไว้ จากนั้นก็เขียนออกมาเป็นทั้ง JSON และ CSV ในรอบเดียว ฟิกซ์เจอร์บทความเป็นตัวอย่างที่ควรหยุดดูดี ๆ Scrapy ไม่พยายามทำความสะอาดหน้าเว็บให้กลายเป็น Markdown สวย ๆ อัตโนมัติ แต่เปิดโอกาสให้ผมเลือกฟิลด์ article ด้วย selector แบบตรงจุด แล้วแยกข้อความ nav กับ footer ไปเก็บในอีกฟิลด์หนึ่ง ดังนั้นผมได้ย่อหน้าหลักครบ 3/3 ส่วนข้อความ boilerplate ก็ถูกกันออกไป ไม่ปนในผลลัพธ์ นี่คือการแลกเปลี่ยน: คุณเขียน selector เอง แล้วได้สิ่งที่ขอเป๊ะ ๆ ไม่มีเกิน ไม่มีขาด
การควบคุม crawl ก็ทำงานได้ตามคาดในสเกลเล็ก ๆ เมื่อเปิด DEPTH_LIMIT=2 ใส่ delay สั้น ๆ จำกัด concurrency ต่อโดเมน และเปิด robots.txt crawl graph ก็เดินผ่าน 11 หน้าใน depth 0, 1 และ 2 อย่างถูกต้อง การจัดการความล้มเหลวก็ไม่ดราม่าเช่นกัน หน้า 500 ที่ตั้งใจให้ล้มกลับมาเป็น item แบบมีโครงสร้าง โดยแสดง status 500 ผ่าน handle_httpstatus_list — ไม่มี exception ไม่มี run ที่ตายกลางทาง Scrapy มอง status error เป็นสิ่งที่คุณจัดการใน logic ของสไปเดอร์ ไม่ใช่เรื่องเซอร์ไพรส์ที่พังทั้ง crawl
ทดลองใช้งานจริง: กำแพงของ JavaScript และประตูที่อยู่ข้าง ๆ กัน

มาถึงผลลัพธ์ที่รีวิวนี้ตั้งใจจะชี้ให้เห็น
ผมให้ HTTP fetcher ของ Scrapy เข้าไปยังฟิกซ์เจอร์แคตตาล็อกที่เรนเดอร์ด้วย JavaScript มันโหลด source HTML มา แล้วพบโหนด .product-card อยู่ 0 รายการ จากนั้นก็ไปต่อ — เพราะมันไม่เคยรันสคริปต์ที่จะวาดการ์ดพวกนั้นออกมา หน้า Quotes to Scrape JS page แบบสาธารณะก็เล่าเรื่องเดียวกัน: โหนดคำคมที่ถูก render มีอยู่ 0 รายการ ถ้าหยุดทดสอบแค่นี้ คุณอาจสรุปว่า Scrapy ใช้ไม่ได้กับอะไรที่สร้างในทศวรรษนี้
แต่ยังไม่ต้องหยุด เพราะแคตตาล็อก JS นั้นจริง ๆ แล้วถูกเติมข้อมูลจาก JSON API เบื้องหลัง เหมือนเว็บส่วนใหญ่ ผมจึงชี้สไปเดอร์ตัวเดิมไปที่ endpoint นั้นโดยตรง แล้วได้สินค้า 8/8 รายการใน 0.416s — ไม่มีเบราว์เซอร์ ไม่มี rendering แค่ยิงไปยัง URL ที่หน้าเว็บนั้นเรียกอยู่แล้ว และ parse JSON ที่ส่งกลับมา
การวางผลลัพธ์สองแบบไว้ข้างกันนี่แหละคือปรัชญา “จำลอง request เดิม” ในรูปเล็ก ๆ หน้าเว็บที่เรนเดอร์แล้วเป็นแค่ฉากลวง ข้อมูลจริงนั่งอยู่หลัง API มาตลอด และดีไซน์ของ Scrapy ก็พาคุณไปยิงตรงนั้น แทนที่จะเสียเวลาจ่ายค่ารัน headless browser เพื่อดูหน้าเว็บค่อย ๆ ประกอบร่างขึ้นมา มันเร็วกว่า เบากว่า และพังยากกว่า — สัญญา API มักนิ่งกว่ากอง DOM ฝั่ง client มาก สิ่งที่ต้องแลกคือความ manual คุณต้องเปิดแท็บ network หา request นั้น แล้วจำลอง headers กับ params เอง Scrapy ไม่ได้ค้นหา API ให้คุณ แต่มันทำให้การยิงไปหา API ง่ายมากเมื่อคุณหาเจอแล้ว
ขอวางขอบเขตให้ชัดอีกสองเรื่อง ถ้าไม่มี request ต้นทางให้จำลองจริง ๆ — เช่นข้อมูลถูกฝังมาจาก client-side rendering โดยไม่มี API อยู่ด้านหลัง — Scrapy จะต้องพึ่ง headless-browser integration ที่คุณเสียบเพิ่มเอง ซึ่งในรอบนี้ผมไม่ได้ทดสอบเส้นทางนั้น และทุกอย่างด้านบนรันกับฟิกซ์เจอร์ขนาดเล็กกับหน้าเดโมสาธารณะเท่านั้น ผมไม่ได้ทดสอบ crawl 100 ถึง 1,000 หน้า ดังนั้นผมจะไม่อ้างเรื่องหน่วยความจำ throughput หรือ retry behavior ในสเกลใหญ่ — แกน async และตัวควบคุม crawl ให้สัญญาณที่ดี แต่สัญญาณไม่ใช่ตัววัดจริง
ข้อดีและข้อเสีย
ข้อดี:
- ดีไซน์แบบ HTTP-only เร็วและเบา — static recall 12/12 ใช้เวลาประมาณครึ่งวินาที, ดึงจาก JSON API 8/8 ใน 0.416s ไม่มีภาระเบราว์เซอร์
- แนวทางจำลอง request เดิมให้ผลจริง: หน้า JS ที่ได้ 0 กลับปล่อยครบทั้ง 8 รายการผ่าน API ต้นทาง
- CSS และ XPath selector ที่ขับด้วย
lxmlทำให้โค้ด extraction อ่านง่ายและทำงานเร็ว - ส่งออกเป็น JSON/CSV/XML ได้เลยโดยไม่ต้องเขียน export plumbing
- จัดการ error แบบชัดเจน — 500 กลับมาเป็น status ที่จับได้ ไม่ใช่ crash
- ตัวควบคุม crawl ครบและสุกงอม: concurrency, delay, depth limits, AutoThrottle, robots.txt
- ใบอนุญาต BSD-3-Clause ใช้เชิงพาณิชย์ได้สบาย และติดตั้งได้เรียบร้อยบนเครื่องปัจจุบัน
ข้อเสีย:
- ไม่เรนเดอร์ JavaScript ตามเจตนา — หน้า client-rendered จะได้ 0 โหนดจนกว่าคุณจะหา API เอง
- การหา request ต้นทางต้องทำเองแบบ manual; Scrapy จะไม่ชี้ endpoint ให้
- สแตก dependency ค่อนข้างใหญ่ (Twisted, lxml, cryptography, pyOpenSSL, parsel, tldextract) — รอบนี้ราบรื่น แต่บนแพลตฟอร์มแปลก ๆ เคยเป็นจุดสะดุด
- ต้องเขียนโค้ดมากกว่าเครื่องมือแบบ no-code หรือ auto-extraction; สไปเดอร์ต้องดูแลเอง
- การทดสอบของผมครอบคลุมแค่ฟิกซ์เจอร์ขนาดเล็กและไซต์เดโม ไม่ใช่ crawl ขนาดใหญ่ — เรื่องความเสถียรในสเกลยังพิสูจน์ไม่จบในรอบนี้
เหมาะกับใคร และใครควรเดินผ่านไป

Scrapy เหมาะกับนักพัฒนาที่อยากคุมทุกอย่างระดับโค้ด และคิดเป็น request ไม่ใช่เป็นหน้าเว็บ ถ้าสัญชาตญาณของคุณเมื่อเจอเว็บ JavaScript ช้าคือ “ข้างในนี้ต้องมี API ซ่อนอยู่แน่” เครื่องมือนี้ถูกสร้างมาเพื่อคนที่คิดแบบนั้นพอดี มันให้รางวัลกับคนที่เขียน selector เป็น อ่าน network tab ออก และพร้อมรับผิดชอบ extraction logic ตั้งแต่ต้นจนจบ สำหรับไซต์แบบ static, แคตตาล็อกที่มี pagination และอะไรที่มี endpoint JSON ให้ค้นเจอได้ มันทั้งเร็วและแม่น
แต่ถ้าคุณไม่อยากใช้เวลาไปกับการเขียนและดูแลสไปเดอร์ หรือถ้าเป้าหมายของคุณเรนเดอร์ข้อมูลเฉพาะฝั่ง client ไม่มี request ให้จำลอง และคุณไม่อยากเสียบ headless browser เอง ก็ควรเดินผ่าน หรืออย่างน้อยก็ใช้คู่กับอย่างอื่น และถ้าในฝันของคุณคือแค่ป้อน URL แล้วได้ผลลัพธ์เป็นโครงสร้างสะอาด ๆ โดยไม่ต้องเขียน extraction rules เลย นั่นไม่เคยใช่งานของ Scrapy และมันก็ไม่เคยอ้างว่าเป็นแบบนั้น
ทางเลือกอื่น และ Thunderbit เข้ามาตรงไหน
ลองใช้ Thunderbit เพื่อดึงข้อมูลเว็บ
เริ่มจากสิ่งที่คุณกำลังเซ็นรับ: เฟรมเวิร์กโอเพนซอร์สใช้ฟรีที่คุณต้องรันและดูแลเอง คุณเป็นเจ้าของสไปเดอร์ สแตก dependency และงานค้นหา data request ของแต่ละไซต์ แลกกับการไม่ต้องจ่ายรายคำขอ เก็บทุกอย่างไว้ในบ้าน และควบคุมได้ทุกจุด สำหรับหลายทีม นั่นคือคำตอบที่ถูกต้อง และรีวิวนี้ไม่ได้มีเจตนาจะชวนให้ใครเลิกใช้แนวทางนั้น
จุดแลกเปลี่ยนจริง ๆ อยู่ที่ปัญหาเรื่อง rendering กับ drift และคำตอบของ Scrapy คือ ให้คุณเป็นคนแก้เอง — คุณหา API, จำลอง request, และถ้าไม่มี API ก็ต้องต่อ headless browser เข้าไปเอง ในทางกลับกัน managed AI scraping API จะยกภาระชั้นนั้นออกจากโต๊ะคุณไปเลย สำหรับผู้อ่านสายเทคนิค สแตกของ Thunderbit คือช่องนั้นพอดี — เป็น AI scraping API บวก MCP server บวก CLI ไม่ใช่ browser extension ที่ทีมขายหรือทีม ops ใช้ POST /distill แปลงหน้าเว็บเป็น Markdown ที่สะอาดและพร้อมใช้กับ LLM; POST /extract ส่งกลับ JSON แบบมีโครงสร้างตาม schema ที่คุณกำหนด; และทั้งคู่รองรับการเรนเดอร์ JavaScript, anti-bot และ dynamic content ฝั่งเซิร์ฟเวอร์ รวมถึงกรณี client-rendered ที่ Scrapy จะบอกให้คุณไปใช้เบราว์เซอร์ นอกจากนี้ยังมี MCP server สำหรับ AI agents และ coding assistants (พร้อม thunderbit_suggest_fields ฟรีสำหรับช่วยสโคปหน้าก่อนเสียเงิน) และมี CLI ผ่าน npx @thunderbit/thunderbit-cli สำหรับงานบน terminal, CI หรือ cron
ความต่างไม่ใช่เรื่องคุณภาพ แต่เป็นเรื่อง ownership Scrapy คือเฟรมเวิร์กเชิงวิศวกรรมที่ชัดเจน: คุณดูแลสไปเดอร์ pipeline และกลยุทธ์เรื่อง JavaScript เอง และได้อำนาจควบคุมเต็มที่โดยไม่มีค่าบริการต่อคำขอ ส่วนสแตกของ Thunderbit จะรับภาระชั้น render-and-extract ไปเป็นบริการที่จัดการให้ คุณจึงไม่ต้องเสียเวลาขุด network tab เอง แต่ต้องจ่ายตามการเรียกใช้งาน แปลว่าถ้าคุณทำงานเล็ก โค้ดต้องมาก่อน และชอบคุมทุกขั้น Scrapy คือ fit ที่ดีกว่า ถ้าคุณต้องสเกลไปหลายร้อยไซต์และไม่อยากจำลอง request ทีละเว็บ แนวทาง managed จะตัดงานทั้งหมวดนั้นออกไปเลย
ถ้าอยากเห็นภาพรวมที่กว้างขึ้น บทสรุปเปรียบเทียบเหล่านี้มีตัวที่ใกล้เคียงกันอยู่แล้ว: การเปรียบเทียบ open-source scraper แบบเต็ม, รีวิว Colly crawler แบบไม่ใช้เบราว์เซอร์ และ รีวิว Scrapling เรื่อง selector แบบปรับตัวได้
บทสรุป
ควรใช้ Scrapy ไหม? ควร — ถ้าคุณเป็นนักพัฒนาที่ต้องการคุมเอง และเชื่อแนวคิดนี้: อย่าเรนเดอร์หน้าเว็บ ให้หา request ที่อยู่ข้างหลังมันแทน ในการทดสอบ แนวคิดนี้ได้ผลตรงตามที่สัญญาไว้ทุกประการ แคตตาล็อก JavaScript ให้ HTTP fetcher ได้แค่ 0 การ์ด แต่ JSON API ที่เลี้ยงมันอยู่ปล่อยข้อมูลทั้ง 8 รายการให้สไปเดอร์ตัวเดิม Static extraction ได้ 12/12 บทความใช้ selector ดึงได้ครบ 3/3 ย่อหน้าโดยไม่ปน boilerplate, crawl graph เคารพ depth limit ตลอด 11 หน้า และ status 500 ถูกจัดการเป็นสถานะแทนที่จะทำให้โปรแกรมล่ม
อย่างไรก็ดี ต้องประเมินความคาดหวังให้ถูก Scrapy ไม่เรนเดอร์ JavaScript และมันจะไม่หา API ให้คุณเอง — สัญชาตญาณตรงนั้นต้องสร้างขึ้นมาโดยคุณเอง สแตก dependency มีขนาดสมกับเป็นเฟรมเวิร์ก และอาจสะดุดบนแพลตฟอร์มแปลก ๆ แม้รอบนี้จะติดตั้งได้เรียบร้อย และผมทดสอบแค่ฟิกซ์เจอร์กับหน้าเดโม ไม่ได้ทดสอบ crawl ระดับพันหน้า ดังนั้นให้มองเรื่องสเกลว่า “มีแนวโน้มดี” แต่ยังไม่ใช่ข้อพิสูจน์ครบถ้วน ภายใต้กรอบนั้น Scrapy คือเครื่องมือที่ยึดแนวคิดที่ดูสวนทางกับกระแส แต่จริง ๆ แล้วเฉียบคมมาก: วิธีที่เร็วที่สุดในการผ่านเว็บเพจ มักไม่ใช่การผ่านหน้าเว็บเพจเลย
ลองใช้ Thunderbit เพื่อดึงข้อมูลเว็บ Get Started Free
คำถามที่พบบ่อย
Scrapy ดึงข้อมูลจากหน้าเว็บที่เรนเดอร์ด้วย JavaScript ได้ไหม? ไม่ได้ด้วย HTTP fetcher แบบค่าเริ่มต้น — ในการทดสอบ มันได้โหนดเป็น 0 ทั้งกับฟิกซ์เจอร์ JS และหน้า Quotes JS สาธารณะ เพราะมันโหลด HTML โดยไม่รันเบราว์เซอร์ แนวทางที่ตั้งใจไว้คือหา data request ที่อยู่เบื้องหลังหน้าเว็บแล้วส่งไปที่ตรงนั้นเลย; ในการทดสอบของผม JSON API ที่อยู่ด้านหลังแคตตาล็อก JS ปล่อยข้อมูลครบ 8 รายการ สำหรับหน้าที่ไม่มี request ให้จำลองจริง ๆ คุณต้องต่อ headless browser เอง
“จำลอง request” หมายความว่าอะไร? หน้าแบบ dynamic ส่วนใหญ่โหลดข้อมูลจาก JSON API เบื้องหลัง แล้วค่อยเรนเดอร์ฝั่ง client แทนที่จะเปิดเบราว์เซอร์เพื่อดูมันเกิดขึ้น คุณเปิดแท็บ network หา API call นั้น แล้วชี้ Scrapy ไปที่มันโดยตรง วิธีนี้เร็วและนิ่งกว่าการเรนเดอร์ — สัญญา API พังยากกว่า DOM — แต่ต้องทำเอง และ Scrapy จะไม่ค้นหา endpoint ให้คุณ
ติดตั้ง Scrapy ยากไหม?
สำหรับผมไม่ยาก — pip install Scrapy==2.17.0 จบแบบไม่มี error เรื่องคอมไพล์ใน venv ใหม่บน macOS โดยใช้ binary wheel แต่ตัวมันดึงสแตกขนาดใหญ่เข้ามา (Twisted, lxml, cryptography, pyOpenSSL, parsel, tldextract) และเอกสารทางการก็ยังเตือนเรื่อง dependency ที่อาจมีปัญหาตามแพลตฟอร์มในบางระบบอยู่ ดังนั้นถ้าคุณใช้เครื่องหรือระบบแปลก ๆ ก็ควรเผื่อไว้
Scrapy รองรับไฟล์ผลลัพธ์แบบไหนบ้าง? Feed export รองรับ JSON, JSON Lines, CSV และ XML มาให้เลย — แค่ชี้สไปเดอร์ไปยังไฟล์ก็ serialize items ออกได้โดยไม่ต้องเขียนโค้ดเพิ่ม ในการทดสอบของผม สไปเดอร์ตัวหนึ่งสร้างได้ทั้ง JSON และ CSV ในรอบเดียว แต่ต้องจำไว้ว่ามันส่งออกตามฟิลด์ที่คุณเลือก ไม่ได้แปลงหน้าเว็บเป็น Markdown ให้อัตโนมัติ
Scrapy ใช้เชิงพาณิชย์ได้ฟรีไหม? ได้ เพราะใช้ BSD-3-Clause ซึ่งเป็นใบอนุญาตแบบค่อนข้างเปิดและเหมาะกับงานเชิงพาณิชย์ อย่างไรก็ตามควรเช็กใบอนุญาตปัจจุบันบน repo ก่อนนำไปสร้างระบบจริง และควรตั้งค่า user-agent, proxy และ rate limit อย่างรับผิดชอบ — ทำได้ ไม่ได้แปลว่าอนุญาตให้ทำอะไรก็ได้


