กลับไปบล็อก

การเลือก crawler แบบโอเพนซอร์ส: 4 บทบาทและ 4 เกณฑ์ประเมิน

การเลือก crawler แบบโอเพนซอร์สจะง่ายขึ้นเมื่อแยกระบบออกเป็น 4 บทบาท ได้แก่ crawling ทั่วไป, browser automation, scheduling และ queue, รวมถึง parsing และ storage บทความนี้อธิบายหน้าที่ ปัญหาที่พบบ่อยเมื่อเชื่อมต่อกัน และเกณฑ์ประเมิน 4 ข้อที่ตรวจสอบได้จริง

เมื่อค้นหา crawler บน GitHub คุณอาจพบ repository หลายร้อยหรือหลายพันรายการ หลายคนเลือกโปรเจกต์จากจำนวนดาว แล้วเริ่มใช้ตัวที่ได้รับความนิยมมากที่สุด

ความนิยมกับความเหมาะสมต่อสถานการณ์จริงเป็นคนละเรื่องกัน ต่อให้โปรเจกต์ได้รับความนิยมมาก หากจุดประสงค์ไม่ตรงกับงานของคุณ ก็อาจทำให้ใช้งานยากขึ้น วิธีเริ่มต้นที่ง่ายกว่าคือแยกหน้าที่ก่อน ระบบเก็บข้อมูลที่ต้องทำงานได้เสถียรในระยะยาวมักประกอบจากหลาย component ที่รับผิดชอบคนละส่วน เมื่อเข้าใจว่าแต่ละส่วนทำอะไร การเปรียบเทียบ implementation ต่าง ๆ ก็จะง่ายขึ้นมาก

开源爬虫项目选型:先分清四类分工,再比四个维度的关键步骤与判断维度示意图

Crawler framework ทั่วไป: สำหรับหน้าเว็บที่มีโครงสร้างคงที่

Framework กลุ่มนี้ดูแล request scheduling, การดึงข้อมูลพร้อมกัน และ data pipeline โดยรับ URL เป็นชุดแล้วส่งออกผลลัพธ์แบบมีโครงสร้าง ระบบนิเวศที่พัฒนาแล้วและ middleware ทำให้สามารถใส่ logic ของตนเองได้ และเหมาะกับงานขนาดใหญ่ที่ต้องรันต่อเนื่องเป็นเวลานาน

แต่ไม่สามารถจัดการหน้าเว็บที่เนื้อหาปรากฏหลัง JavaScript render ได้ด้วยตัวเอง ในกรณีนี้ response แรกจะเป็นเพียงโครงเปล่า จึงต้องต่อ rendering engine เพิ่ม เหมาะกับเป้าหมายที่โครงสร้างเสถียร เช่น หน้ารายการ หน้ารายละเอียด และ API แบบเปิด

Browser automation framework: สำหรับการ render และ interaction

หน้าเว็บที่ต้อง render จริง ต้องมีสถานะ login หรือจำเป็นต้องคลิกหลายครั้งก่อนเห็นเนื้อหา ควรใช้ browser automation เครื่องมือเหล่านี้สามารถทำงานกับ browser engine หลายแบบ มีกลไกรอที่พัฒนาแล้ว และสามารถจัดการ request กับ response ของหน้าได้โดยตรง

ข้อแลกเปลี่ยนคือใช้ทรัพยากรมากกว่า HTTP request แบบตรง ๆ อย่างชัดเจน จำนวนงานพร้อมกันสูงสุดขึ้นอยู่กับ memory และ CPU ของเครื่องเป็นหลัก นอกจากนี้ automation ยังทิ้งลักษณะที่ตรวจจับได้ ทำให้เว็บไซต์ที่มีระบบตรวจสอบเข้มงวดอาจระบุได้

Scheduling และ queue: จำเป็นเมื่อจำนวนงานเพิ่มขึ้น

หากมีเป้าหมายน้อย loop ธรรมดาอาจเพียงพอ แต่เมื่อมี tasks หลายพันรายการและต้องควบคุมความถี่กับ retry จะต้องมี scheduling layer แยกต่างหาก เช่น จะจัดคิวอย่างไร เปิด concurrency เท่าไร หลังล้มเหลวรอนานแค่ไหนก่อน retry และ task ไหนควรยกเลิก ถ้ายัด logic ทั้งหมดไว้ใน crawler framework โค้ดจะซับซ้อนและดูแลยากขึ้นเรื่อย ๆ

ข้อผิดพลาดที่พบบ่อยเมื่อต่อ layer นี้เองคือใช้ queue ที่อยู่เฉพาะใน process เมื่อ process restart งานที่รอทั้งหมดจะหายไป อย่างน้อย queue ควรเก็บข้อมูลได้แบบถาวรและตรวจสอบ status ได้

Parsing และ storage: ตัดสินว่าข้อมูลพร้อมใช้หรือไม่

สิ่งที่ดึงกลับมาคือ HTML แต่สิ่งที่ต้องใช้จริงคือ fields ชั้น parsing ควรจัดการ extraction rules, ตรวจสอบ fields, กำจัดข้อมูลซ้ำ และเขียนลง storage สำหรับเว็บไซต์ที่เปลี่ยนโครงสร้างบ่อย อาจพิจารณา adaptive extraction ที่หา data จากคุณลักษณะของหน้าแทน selector ที่เขียนตายตัว เพื่อลดงานบำรุงรักษา

ฝั่ง storage ต้องใส่ใจ idempotency ด้วย การ retry task เป็นเรื่องปกติ ดังนั้นการเขียนข้อมูลควรกำจัดรายการซ้ำด้วย unique identifier มิฉะนั้นข้อมูลซ้ำจะไหลไปกระทบการวิเคราะห์ downstream

ปัญหาที่เกิดขึ้นบ่อยหลังนำส่วนต่าง ๆ มาต่อกัน

แต่ละ component แยกกันไม่ได้ซับซ้อนมาก ปัญหามักเกิดตรงรอยต่อ

  • Scheduling layer retry งาน แต่ parsing layer ไม่กำจัดข้อมูลซ้ำ จึงเกิดแถวซ้ำ
  • Browser layer ไม่มี concurrency limit ทำให้ทรัพยากรในเครื่องหมดและทั้ง batch ล้มเหลว
  • Parsing rules ถูก hard-code ไว้ในโค้ด พอเว็บไซต์เปลี่ยนก็ต้องปล่อยเวอร์ชันใหม่
  • แต่ละ component ใช้ identifier ของ task ไม่เหมือนกัน ทำให้ status ไม่ตรงกันและ resume จาก checkpoint ไม่ได้

เกณฑ์ประเมิน 4 ข้อ

เมื่อเลือกประเภทที่ต้องการได้แล้ว ให้ใช้ 4 ข้อนี้คัดโปรเจกต์ที่เจาะจง

สำหรับความ active ของ maintenance ให้ดู commit frequency และความเร็วในการตอบ issue ในช่วงไม่กี่เดือนล่าสุด แทนการดูจำนวนดาวทั้งหมด โปรเจกต์ที่หยุดดูแลอาจใช้งานไม่ได้ทันทีเมื่อ target site เปลี่ยนแปลง

Documentation และตัวอย่างเป็นตัวกำหนดต้นทุนในการเริ่มใช้งาน ถ้าเอกสารคลุมเครือหรือมีเพียงตัวอย่างง่ายที่สุด เวลาเรียนรู้มักมากกว่าที่คาด

ด้าน extensibility ให้ดูว่ามีจุดเชื่อมต่ออะไรไว้บ้าง เปลี่ยน proxy ได้หรือไม่ ต่อ rendering engine ของตนเองได้หรือไม่ และเปลี่ยน storage ได้หรือไม่ โปรเจกต์ที่มี extension points ชัดเจนช่วยให้ปรับภายหลังได้โดยไม่ต้องแก้ source code

ความเสี่ยงด้าน license และ compliance มักถูกมองข้าม ก่อนใช้งานเชิงพาณิชย์ให้ยืนยันประเภท license และหลีกเลี่ยง license ที่ขัดกับรูปแบบการใช้งานของคุณ ควรประเมินขอบเขตการเก็บข้อมูล ความถี่ request และเงื่อนไขของ target site ด้วย ซึ่งเป็นคนละเรื่องกับคุณภาพทางเทคนิคของ framework

Environment layer เป็นอีกระดับหนึ่ง

Framework แก้ปัญหาว่าจะเก็บข้อมูลอย่างไร แต่ไม่ได้แก้เรื่อง identity และ scale เมื่อ task ต้อง login ต้องแยกตามภูมิภาค หรือใช้หลาย account พร้อมกัน การรันทั้งหมดใน browser environment เดียวจะทำให้เกิดสองปัญหา session ปะปนกันเพราะ cookies และ local storage ซ้อนทับกัน และ target site อาจมอง task ที่ไม่เกี่ยวข้องกันว่าเป็นการเข้าถึงกลุ่มเดียวกัน

แนวทางที่พัฒนาแล้วกว่าคือทำ browser environment ให้เป็น resource layer แยกต่างหาก Task ขอ environment จาก pool และคืนเมื่อใช้เสร็จ ใน architecture แบบนี้ PurpleMark อยู่ใน layer นี้ โดยให้ environment resources ที่สร้างเป็น batch ได้ ผูกกับ network egress แยกกันได้ และตรวจสอบ status ได้

ขอบเขตด้าน compliance

ปฏิบัติตาม robots rules และ terms of service ของ target site ไม่เก็บ personal information ไม่หลบเลี่ยง technical protection measures และควบคุม request frequency ไม่ให้กระทบการให้บริการตามปกติ การเลือกโปรเจกต์แก้เรื่องประสิทธิภาพ ส่วนการพิจารณาเหล่านี้ใช้ตัดสินว่าควรทำการเก็บข้อมูลหรือไม่