ตัวดึงข้อมูลที่รั่วโบลต์เพลตมากที่สุด แต่ก็ไม่พลาดเนื้อหาสักชิ้นในชุดทดสอบนี้

อัปเดตล่าสุดเมื่อ August 14, 2026
ตัวดึงข้อมูลที่รั่วโบลต์เพลตมากที่สุด แต่ก็ไม่พลาดเนื้อหาสักชิ้นในชุดทดสอบนี้
สรุปด้วย AI
มีไลบรารี 6 ตัว ชุดฟิกซ์เจอร์ที่ติดป้ายกำกับ 1 ชุด และตัวคำนวณคะแนน 1 ตัว ในฟิกซ์เจอร์สังเคราะห์ 22 ชุดนี้ ไลบรารีที่รั่วโบลต์เพลตมากที่สุด — Mozilla's Readability ที่ 23.5% — กลับเป็นตัวเดียวที่กู้หน่วยบทความที่ติดป้ายไว้ได้ครบทุกชิ้น นี่คือข้อแลกเปลี่ยนทั้งหมดในประโยคเดียว และบทความส่วนใหญ่ที่เขียนเรื่องนี้ไม่เคยพูดถึง เพราะมักจะหยุดอยู่แค่การวัด precision แล้วจบ ถ้าจะป้อนให้โมเดลแล้วจ่ายตาม token? newspaper4k หรือ goose3 คือคำตอบ ทั้งคู่ไม่รั่วโบลต์เพลตและไม่มี token ปนเปื้อน newspaper4k เหมาะถ้าคุณต้องการคำตอบทุกหน้า ส่วน goose3 เหมาะถ้าคุณยอมเงียบดีกว่าการเดา และหน้าเว็บของคุณมี paragraph

มีไลบรารี 6 ตัว ชุดฟิกซ์เจอร์ที่ติดป้ายกำกับ 1 ชุด และตัวคำนวณคะแนน 1 ตัว ในฟิกซ์เจอร์สังเคราะห์ 22 ชุดนี้ ไลบรารีที่รั่วโบลต์เพลตมากที่สุด — Mozilla's Readability ที่ 23.5% — กลับเป็นตัวเดียวที่ดึงหน่วยบทความที่มีป้ายกำกับไว้ครบทุกชิ้น

นี่คือข้อแลกเปลี่ยนทั้งหมดในประโยคเดียว และบทความส่วนใหญ่ที่เขียนเรื่องนี้ไม่เคยพูดถึง เพราะมักจะหยุดอยู่แค่การวัด precision แล้วจบ

วัดอะไรกันแน่

ฟิกซ์เจอร์ทุกชุดในงานนี้มีค่า ground truth แยกตามหน่วย แต่ละบล็อกของหน้าเว็บ — ย่อหน้าบทความ เมนูนำทาง โฆษณา แถบด้านข้าง เธรดคอมเมนต์ และโปรโมชัน — ถูกติดป้ายว่า article หรือ boilerplate พร้อม sentinel token เฉพาะของตัวเอง ดังนั้นคำถามว่า “ตัวดึงข้อมูลกู้หน่วยนี้กลับมาได้ไหม” จึงตรวจจากการมีซับสตริงแบบตรงตัว ไม่ใช่การวัดความคล้ายเคียง Sentinel ตัวนั้นอยู่ในผลลัพธ์ หรือไม่อยู่ เท่านั้น

ฟิกซ์เจอร์ 22 ชุด มี 91 หน่วย ใช้ตัวดึงข้อมูล 6 ตัว ได้แก่ Mozilla Readability 0.6.0 (ผ่าน jsdom 30.0.1), trafilatura 2.2.0, resiliparse 1.0.9, newspaper4k 0.9.6, goose3 3.1.22 และ jusText 3.0.2 ใช้ Python 3.14.2 และ Node 22 บนเครื่องเดียวกัน บทความนี้ไม่ได้เก็บ OS/CPU, คำสั่งที่ใช้จริง, จำนวนครั้งที่รันซ้ำ หรือวิธี warm-up ไว้ครบ ดังนั้นคอลัมน์เวลาเป็นเพียงข้อสังเกตบนเครื่องนี้ ไม่ใช่ benchmark ที่นำไปใช้อ้างอิงข้ามเครื่องได้

ก่อนเริ่มรัน ผมตั้งกฎไว้ 2 ข้อ ข้อแรก ไลบรารี Python ทุกตัวติดตั้งลงใน virtualenv ว่างของตัวเอง เพื่อให้ footprint เป็นของมันจริง ๆ ไม่ได้สืบทอดจากแพ็กเกจที่ตัวอื่นดึงเข้ามา ข้อสอง ไม่มี runner ตัวไหนคำนวณ metric เอง — ทุกตัวแค่ dump ข้อความดิบที่ดึงออกมา แล้วมี scorer ตัวเดียวสร้างตัวเลขทุกค่า เพื่อให้ทั้ง 6 เครื่องมือถูกเปรียบเทียบด้วยสูตรเดียวกันจริง ๆ ไม่ใช่ด้วยนิยามคำว่า “precision” ที่ดูคล้ายกันแต่ต่างกัน

ตารางสรุปหลัก

ไลบรารีArticle recall (ครบ 22)Boilerplate leakContent-token precisionจำนวนฟิกซ์เจอร์ precision ที่ตอบได้Contaminating tokens
Readability1.00000.23530.910911/1135
trafilatura0.98650.05880.941111/114
newspaper4k0.98650.00000.945211/110
resiliparse0.90540.05880.938111/117
jusText0.83780.47060.876010/1174
goose30.82430.00001.000010/110

Recall คิดรวมจากฟิกซ์เจอร์ทั้ง 22 ชุด อัตราการรั่ว, content-token precision รวม และ contamination ใช้เฉพาะ 11 ฟิกซ์เจอร์ที่มีทั้ง article และ boilerplate; คำว่า “answered” คือจำนวนฟิกซ์เจอร์ที่ให้ผลลัพธ์ออกมา รายละเอียดรายฟิกซ์เจอร์ทั้งหมดอยู่ใน sixway-scores.json.

หนึ่งแถวในตารางนี้ไม่ใช่ค่าเริ่มต้น resiliparse ใช้ extract_plain_text ที่ค่าเริ่มต้นของมันคือ main_content=False แต่ผมเรียกด้วย main_content=True ความต่างนี้ไม่ใช่น้อย: ถ้าใช้ค่า default มันรั่ว 17 จาก 17 หน่วยโบลต์เพลตทั่วทั้งชุด — ทั้งเมนู โฆษณา แถบด้านข้าง เธรดคอมเมนต์ และโปรโมชัน — เทียบกับ 1 จาก 17 เมื่อเปิดแฟลกนี้ ไลบรารีอื่นทั้งหมดในตารางถูกเรียกด้วยค่า default ดังนั้น leak rate 0.0588 ของ resiliparse จึงสะท้อนผลเมื่อขอเฉพาะ main content จริง ๆ ส่วน extract_plain_text(html) แบบไม่ใส่อะไรเพิ่มเป็นอีกพฤติกรรมหนึ่ง (default-vs-main-content.json).

อ่านคอลัมน์แรกกับคอลัมน์ที่สองไปพร้อมกัน เพราะถ้าอ่านแยกกัน คุณจะเลือกเครื่องมือผิด

Readability ไม่พลาดเลย Recall เต็ม 22 จาก 22 ฟิกซ์เจอร์ และมีแค่ตัวเดียวที่ทำได้แบบนั้น แต่มันจ่ายราคาด้วยการรั่วหน่วยโบลต์เพลต 4 จาก 17 หน่วย มี contaminating tokens 35 ตัว มากกว่า trafilatura ถึง 4 เท่า การรั่ว 3 ใน 4 ครั้งมีรูปแบบเดียวกัน — เป็นบล็อกโปรโมชันที่ถูกจัดอยู่ในคลาสกลาง ๆ และวางเป็นพี่น้องกับบทความ ซึ่ง heuristic แบบเอาบล็อกข้างเคียงมาต่อทำให้มันกลืนเข้าไป ถ้าคุณเอาผลลัพธ์นี้ไปป้อนโมเดล คุณกำลังจ่ายค่าทุก token เหล่านั้น และโมเดลก็อ่านมันเหมือนเป็นบทความจริง

newspaper4k คือสมดุลที่สุด ไม่รั่วเลย ไม่มี contaminating tokens เลย recall 0.9865 และให้ผลลัพธ์ครบทั้ง 22 ฟิกซ์เจอร์ ถ้าผมต้องเลือกตัวเดียวโดยไม่รู้ลักษณะงานล่วงหน้า ผมเลือกตัวนี้ และมันไม่ใช่ตัวที่คนส่วนใหญ่หยิบก่อน

goose3 มี precision สมบูรณ์แบบ แต่ recall แย่ที่สุดในการทดสอบ ทุกคำที่มันคืนกลับมาเป็นเนื้อหาบทความจริง ๆ แต่ก็มี 2 ฟิกซ์เจอร์ที่มันคืนกลับมาเป็นศูนย์ และไม่มีผลลัพธ์เลยในทั้งสองชุดนั้น precision ที่ดูดีมากเป็นเรื่องง่าย ถ้าคุณมีสิทธิ์ปฏิเสธการตอบ

ตัวเลข precision ที่ทำให้สองไลบรารีดูดีเกินจริง

ประเด็นนี้ควรพูดให้ชัด เพราะผมเกือบเผยแพร่ผิดไปแล้ว

precision และ F1 ในที่นี้คำนวณเฉพาะกรณีที่มี output เท่านั้น ไลบรารีที่คืนค่าว่างบนฟิกซ์เจอร์หนึ่งชุด จะไม่เพิ่มทั้งตัวเศษและตัวส่วน — ดังนั้นการไม่ตอบจึงแทบฟรี และ precision ของตัวดึงข้อมูลแบบระมัดระวังจึงดูดีกว่าตัวที่พยายามดึงมากกว่า โดยไม่มีเหตุผลอื่นนอกจากมันเงียบ

goose3 มี precision รวม 1.0000 ใน 10 ฟิกซ์เจอร์ที่ได้คะแนนและมันคืน output ออกมา ส่วน jusText อยู่ที่ 0.8760 จาก 10 ใน 11 ฟิกซ์เจอร์ Readability, trafilatura, resiliparse และ newspaper4k ตอบครบ 11 จาก 11 ตารางตอนนี้จึงแสดงตัวส่วนไว้ข้าง ๆ precision เพื่อไม่ให้การไม่ตอบหายไปหลังอัตราส่วนที่ดูสวย

และยังมีเวอร์ชันที่แย่กว่านี้อีก เวอร์ชันแรกของ scorer ของผมเฉลี่ย article recall บนชุด content-fidelity 11 ฟิกซ์เจอร์ชุดเดียวกัน — ชุดที่ตัดฟิกซ์เจอร์ที่ไม่มี boilerplate ออก ซึ่งเป็นการตัดที่ถูกต้องสำหรับการวัด leak ผลที่ได้บอกว่า resiliparse มี recall 1.0000 แต่เมื่อคิดครบทั้ง 22 ฟิกซ์เจอร์ มันอยู่ที่ 0.9054 เพราะบนฟิกซ์เจอร์ที่บทความอยู่ใน <li> ทั้งหมดและไม่มี <p> เลย มันยังคืนผลลัพธ์กลับมา แต่กู้หน่วยบทความได้ 0 จาก 6 ฟิกซ์เจอร์นั้นไม่มี boilerplate จึงหลุดออกจากค่าเฉลี่ย และความล้มเหลวจริงถูกซ่อนอยู่หลังคะแนนที่ดูสมบูรณ์แบบ

แต่ละตัวพังตรงไหนจริง ๆ

ฟิกซ์เจอร์ทดสอบอะไรใครกู้เนื้อหาไม่ได้เลย
บทความอยู่ใน <li> ทั้งหมด ไม่มี <p>สมมติฐานด้านโครงสร้างresiliparse (0/6), goose3 (ไม่มี output)
หน่วยบทความเดียว ยาว 129 ตัวอักษรthreshold ของเนื้อหาสั้นjusText
10 ย่อหน้าสั้น ไม่มีตัวที่ยาวthreshold ของเนื้อหาสั้นjusText
เอกสารแทบว่างขอบเขตศูนย์จริง ๆgoose3, jusText

ทุกกรณีข้างต้นเป็นพฤติกรรมที่เฉพาะเจาะจงและทำซ้ำได้ ไม่ใช่คำว่า “แย่กว่าการดึงข้อมูลทั่วไป” แบบกว้าง ๆ:

  • resiliparse และ goose3 ต่างก็สมมติว่ามี paragraph ถ้าคุณชี้ไปที่หน้าซึ่งเนื้อหาหลักเป็นรายการ — changelog, spec, FAQ, recipe — resiliparse จะส่งข้อความกลับมาโดยไม่มีเนื้อหาในรายการนั้นเลย ส่วน goose3 จะไม่คืนอะไรกลับมาเลย resiliparse อันตรายกว่าตรงที่การได้ “อะไรบางอย่าง” ดูเหมือนสำเร็จ
  • jusText มีหน้าผาเรื่องความยาว และชันมาก อธิบายต่อด้านล่าง
  • เอกสารแทบว่างเป็นกรณีเดียวที่การไม่คืนอะไรกลับมาอาจจะถือว่าถูกต้อง ผมจึงไม่ถือว่าเป็นความผิดของทั้งสองตัวนั้น

jusText: เป็นหน้าผา ไม่ใช่ทางลาด

jusText ให้ output ใน 19 จาก 22 ฟิกซ์เจอร์ และรั่ว boilerplate 47% ซึ่งเป็นค่าสูงสุดในการทดสอบ ตรงข้ามกับชื่อเสียงของมัน แต่ตัวเลขที่น่าสนใจจริง ๆ คือค่าที่ทำให้ผมต้องรันทุกอย่างใหม่

jusText จัดประเภทแต่ละบล็อกจากความหนาแน่นของ stopword เทียบกับ stoplist ของภาษา แล้วค่อยทำรอบที่อาศัยบริบทเพื่อดันบล็อก neargood ให้เป็น good เฉพาะเมื่อมันอยู่ข้างบล็อก good ที่มีอยู่แล้ว บล็อกจะกลายเป็น good ได้ด้วยตัวเองก็ต่อเมื่อยาวเกิน length_high ซึ่งค่า default คือ 200 ตัวอักษร ถ้าเอกสารไหนไม่มีอะไรยาวถึงเส้นนั้น ก็ไม่มีอะไรไปเป็นตัวตั้งต้นให้การดันสถานะ และทั้งหน้าจะค่อย ๆ กลายเป็น boilerplate

ผมไล่ทดสอบบนเอกสารที่ย่อหน้าที่ยาวที่สุดมี 151 ตัวอักษร:

length_highจำนวนย่อหน้าที่เป็น Goodจำนวนตัวอักษรที่คืนมา
200 (default)00
1508832
1208832
1008832
808832

จาก 0 ไป 832 ตัวอักษร เมื่อมีแค่ย่อหน้าเดียวที่ข้าม threshold แล้วหลังจากนั้นต่อให้ลดลงอีกเท่าไรก็ไม่เปลี่ยนอะไรอีก ย่อหน้าเพียงหนึ่งเดียวที่ข้ามเส้นไปได้ จะปลดล็อกทั้งเอกสาร

ก่อนจะสรุปแบบนั้น ผมยังไล่ length_low 4 ค่า และ max_link_density 2 ค่า — รวม 8 ชุดค่าผสม และทุกชุดให้ศูนย์หมด ตามกฎของโปรเจกต์นี้ ถ้าจะกล่าวอ้างว่าทำอะไรไม่ได้ ต้องลองอย่างน้อย 3 รูปแบบของพารามิเตอร์หรือมี error จาก vendor ที่ระบุชัดว่าฟิลด์นั้นผิด และพารามิเตอร์ที่ไม่ก่อผลเพียงตัวเดียวไม่ใช่ข้อสรุปเกี่ยวกับตัวไลบรารีเอง ตัวเลขทั้งหมดอยู่ใน justext-length-threshold.json

ทั้งหมดนี้ไม่ได้บอกว่า jusText ดึงข้อมูลแย่ บนหน้าเนื้อหาภาษาอังกฤษจริง ๆ ที่ใช้ค่า default มันคืนข้อความบทความสะอาด ๆ ถึง 1,190 ตัวอักษร สิ่งที่มันบอกคือ jusText มีตัวปรับที่เอกสารระบุไว้ ซึ่งทำงานเหมือนสวิตช์ และตำแหน่ง default ของสวิตช์นี้ไม่เหมาะกับเอกสารที่ใช้ย่อหน้าสั้น

สิ่งที่คุณติดตั้ง และต้นทุนตอน import

Measured results chart: Install footprint vs cold import

ฟิกซ์เจอร์ชุดเดียวกัน เครื่องเดียวกัน ไลบรารีแต่ละตัวอยู่ใน virtualenv ว่างของตัวเอง

ไลบรารีPackagessite-packagesCold importExtraction p50
resiliparse521.0 MiB0.015 s0.06 ms
jusText322.4 MiB0.777 s0.56 ms
goose31644.3 MiB2.181 s1.85 ms
newspaper4k2247.5 MiB2.812 s2.69 ms
trafilatura1769.9 MiB1.584 s0.51 ms
Readability + jsdom32 (npm)26 MiB0.473 s6.37 ms

ในการรันครั้งนี้ resiliparse มีค่า cold-import และ median extraction ต่ำที่สุด: 15 ms และ 0.06 ms แต่ถ้าจะเทียบข้าม runtime แบบเป็นอัตราส่วนเป๊ะ ๆ จะเกินกว่าที่โปรโตคอลที่ยังไม่ครบนี้รองรับ โดยเฉพาะเพราะการ extraction ที่ช้าที่สุดเพียงครั้งเดียวอยู่ที่ 1,098 ms ก่อนจะเอาตัวเลขชุดนี้ไปใช้กับการ sizing สำหรับ serverless จำเป็นต้องแยกดูการเริ่มต้น, การเรียกครั้งแรก และ steady-state distribution ก่อน

trafilatura กับ resiliparse สูสีมากในด้านคุณภาพ — content-token F1 อยู่ที่ 0.9697 เทียบ 0.9681 และ leak rate เท่ากันที่ 0.0588 — ผมไม่ขอฟันธงผู้ชนะจากความต่างแค่นั้น ส่วน footprint ไม่ได้ใกล้กันเลย: 21.0 MiB เทียบ 69.9 MiB, 5 แพ็กเกจเทียบ 17 สิ่งที่คุณกำลังแลกจริง ๆ คือความไม่ถนัดกับรายการของ resiliparse แลกกับ prerequisite เพิ่มอีก 3 ตัวของ trafilatura

2 บั๊กใน testbed ของผมเอง ที่เจอก่อนเผยแพร่

การเปรียบเทียบข้างบนเกือบไม่ได้เกิดขึ้น และเหตุผลนี้มีค่าน่ารู้มากกว่าหนึ่งแถวในตารางใด ๆ

ชุดฟิกซ์เจอร์เดิมมองไม่เห็นไลบรารี 2 จาก 6 ตัว ฟิกซ์เจอร์ต้นฉบับเขียนทุกหน่วยเป็นชุด token ที่ไร้ความหมายและไม่ซ้ำกัน — zzart01vf64 zzart01v56i — ซึ่งนั่นแหละที่ทำให้การวัด recall แบบตรงตัวทำงานได้ แต่มันก็หมายความว่าฟิกซ์เจอร์เหล่านั้นไม่มี function words ภาษาอังกฤษเลย Readability, trafilatura และ resiliparse ตัดสินจากโครงสร้างใน DOM จึงไม่กระทบ goose3 และ jusText ตัดสินจากภาษาโดยนับ stopword และไม่มีอะไรให้มันนับ: ทั้งสองตัวคืนค่าว่างทั้งหมด 22 ฟิกซ์เจอร์

ตารางที่ให้ 2 ไลบรารีได้ศูนย์คงดูเหมือนน่าเชื่อถือ แต่จริง ๆ ไม่ได้บอกอะไร ผมตรวจสอบก่อนจะเขียนมันด้วยหน้าจริง ๆ: goose3 คืนมา 1,017 ตัวอักษร และ jusText 1,190 ตัวอักษร ตัวไลบรารีไม่ได้มีปัญหา testbed ต่างหากที่แทนพวกมันไม่ได้

ดังนั้นจึงสร้างฟิกซ์เจอร์ใหม่โดยใช้ prose ภาษาอังกฤษที่ฝัง sentinel ไว้ — โครงสร้างเดิม คลาสเดิม ตำแหน่งใน DOM เดิม ขอบเขตหน่วยเดิม sentinel เดิม สลับ token ไป 1,568 ตัว goose3 กระโดดจาก 0 เป็น 20 จาก 22 ฟิกซ์เจอร์

แต่จากนั้นการสร้างใหม่ก็ทำให้สองอย่างพัง และทั้งสองอย่างเป็นความผิดของผมเอง คำอังกฤษหนึ่งคำยาวประมาณ 6 ตัวอักษร ส่วน zzart01vf64 ยาวประมาณ 12 ตัวอักษร การแทนแบบ 1 ต่อ 1 ทำให้ทุกหน่วยสั้นลงครึ่งหนึ่ง — ข้อความหน่วย 21,646 ตัวอักษรเหลือ 10,986 ตัวอักษร และหน่วยที่ยาวที่สุดตกจาก 1,513 เหลือ 622 นี่ไปเขียนฟิกซ์เจอร์ที่แกนหลักคือ “ความยาว” ทับเงียบ ๆ jusText ซึ่งพฤติกรรมเป็นหน้าผาความยาว จึงตกจาก 19 จาก 22 เหลือ 6 จาก 22 แค่เพราะเรื่องนี้อย่างเดียว ถ้าผมเผยแพร่เวอร์ชันที่สั้นลงครึ่งหนึ่ง ตัวเลขของ jusText จะผิดไปถึง 3 เท่า ในทิศทางที่ทำให้มันดูแย่กว่าความจริง

อย่างที่สอง: การดึงหน่วยทั้งหมดมาจาก corpus ร่วมชุดเดียวกันทำให้ความหนาแน่นของ stopword กลับมาถูกต้อง แต่ทำลายคุณสมบัติที่การให้คะแนนระดับ token ต้องพึ่งพา vocabulary ของ article กับ boilerplate ต้องไม่ทับกัน ไม่อย่างนั้น “token ที่ดึงออกมาและเป็น token ของ boilerplate” จะไปนับคำว่า the แทน ฟิกซ์เจอร์ 10 จาก 22 ชุดลงเอยด้วย vocab ที่ซ้อนทับกัน เทียบกับ 0 ในต้นฉบับ วิธีแก้คือเติม suffix ให้คำเนื้อหาในแต่ละหน่วย และปล่อย function words ไว้แบบเดิม — ให้ library เชิง lexical มี stopword จริง ๆ ให้นับ และให้ scorer มี content vocabulary ที่ไม่ทับกัน

นั่นคือเหตุผลด้วยว่าทำไมคอลัมน์ระดับ token ที่นี่จึงชื่อ content_token_* และไม่ได้เอาชื่อซ้ำจาก benchmark Readability-versus-trafilatura ที่เผยแพร่ไปแล้ว มันคือปริมาณคนละตัว วัดเฉพาะคำเนื้อหา และถ้าอ้างผิดก็จะผิดจริง

ระหว่างการสร้างใหม่ ยังมีอีกอย่างที่ไม่ใช่ความผิดของผมโผล่มา: ฟิกซ์เจอร์ link-density 3 ชุดวาง </a> ไว้กลางคำ<a href="/x">zzsibp015qlhf zzsi</a>bp015qbht — เพราะตำแหน่ง anchor ถูกวางด้วย character offset เพื่อให้ได้ ratio ที่ต้องการพอดี ข้อความที่ render ออกมาไม่เปลี่ยน ดังนั้นการให้คะแนนแบบเดิมจึงไม่เห็นปัญหา แต่ตัวดึงข้อมูลที่ทำงานระดับ element แทนที่จะมองเป็น text run จะเห็นเป็น 2 ชิ้น ในขณะที่ตัวอื่นเห็นเป็นคำเดียว แก้เรียบร้อย พร้อมบันทึก delta ของตัวอักษรที่ถูกลิงก์ไว้ แทนที่จะกลืนเงียบ ๆ

ใครควรใช้ตัวไหน

ถ้าจะป้อนให้โมเดลแล้วจ่ายตาม token? ใช้ newspaper4k หรือ goose3 ทั้งคู่ไม่รั่วโบลต์เพลตและไม่มี contaminating tokens newspaper4k เหมาะถ้าคุณต้องการคำตอบทุกหน้า goose3 เหมาะถ้าคุณยอมเงียบดีกว่ากลัวเดาสุ่ม และหน้าเว็บของคุณมี paragraph

ถ้าคุณเน้น latency ฝั่ง Python? ใส่ resiliparse เข้าไปในรอบเทียบ มันมีค่า import และ median extraction ต่ำที่สุดในการทดสอบนี้ และคุณภาพก็ใกล้ trafilatura มาก — แต่ต้องเปิด main_content=True ซึ่งไม่ใช่ค่า default ก่อน และอย่าแปลงเวลาท้องถิ่นนี้เป็นอัตราส่วนความเร็วข้าม runtime แบบเป๊ะ ๆ

ถ้าจะเก็บถาวร หรือกรณีที่การพลาดเนื้อหาแย่กว่าการมีเนื้อหาเกิน? เลือก Readability เพราะมันเป็นตัวเดียวที่กู้หน่วยบทความครบทุกฟิกซ์เจอร์ และการมี token หลุดมา 35 ตัวถือว่าถูกมาก ถ้าทางเลือกคือทำให้ย่อหน้าหายไป

งานหลายภาษา? jusText เป็นตัวที่ควรพิจารณา เพราะมันมากับ stoplist หลายภาษา งานนี้ไม่ได้ทดสอบการดึงข้อมูลหลายภาษา ดังนั้นคุณสมบัตินี้เป็นเหตุผลให้ลอง ไม่ใช่หลักฐานว่ามันชนะ ให้ลอง length_high กับความยาวย่อหน้าที่ใกล้เคียงงานจริงของคุณ

ถ้าไม่ใช่บทความล่ะ? ไม่มีตัวไหนตอบโจทย์ พวกมันทั้งหมดสร้างบนสมมติฐานว่าหน้าหนึ่งมีเนื้อหาแกนกลางเป็น prose และหน้า product listing, search results หรือ dashboard จะทำลายสมมตินั้น ซึ่งไม่มีพารามิเตอร์ไหนแก้ได้

ตำแหน่งของ managed API

ทุกอย่างข้างบนคือไลบรารีที่คุณรันเอง: คุณให้ HTML ไป แล้วรับข้อความกลับมา โหมดพังที่เห็นแตกต่างกันไปตามรูปหน้าเว็บ ดังนั้นควรตรวจค่า default ที่เลือกกับ corpus ของคุณเองก่อน ส่วนการดึงฟิลด์แบบมีโครงสร้าง และการ fetch/render นั้นอยู่นอกการเปรียบเทียบนี้

หมายเหตุผู้เขียน: Thunderbit คือบริการแบบ managed สำหรับ workflow ที่มี URL เป็น input และผลลัพธ์แบบมีโครงสร้าง บริการนี้ไม่ได้ถูกรันผ่านฟิกซ์เจอร์ชุดนี้ จึงไม่ได้สื่อว่าคุณภาพดีกว่าหรือแย่กว่า จุดตัดสินใจที่สำคัญคือ คุณมี HTML อยู่แล้วและต้องการตัวดึงข้อความในเครื่อง หรืออยากให้บริการจัดการทั้งการ fetch/render และงานปฏิบัติการให้

พูดแบบตรงไปตรงมา: ถ้าคุณมี HTML อยู่แล้วและต้องการข้อความ หนึ่งใน 6 ตัวนี้ฟรีและใช้งานได้ดี และตารางนี้บอกได้ว่าควรเลือกตัวไหน ถ้าคุณกำลังดึงหน้าเว็บในสเกลใหญ่ หรือคุณต้องการข้อมูลเป็นแถวแทน prose นั่นคือการซื้ออีกแบบหนึ่ง

ถ้าคุณกำลังเลือกระหว่าง hosted fetcher แทนล่ะก็ บทสรุป web scraping API roundup ของเราครอบคลุมตลาดนั้น และบทความ cost comparison of SEO and data APIs ครอบคลุมเรื่องราคา ส่วนฝั่ง self-hosted, open-source scraper pillar ให้ภาพรวมที่กว้างกว่า และถ้าสิ่งที่คุณต้องการจริง ๆ คือ Markdown ไม่ใช่ plain text, converting HTML to Markdown in Python คือจุดที่สูญเสียมากที่สุด

ลองใช้ Thunderbit สำหรับการดึงข้อมูลเว็บ

บทสรุป

ไม่มีผู้ชนะ และถ้าตารางไหนอ้างว่ามีหนึ่งเดียว นั่นคือการบิดเบือนข้อแลกเปลี่ยนจริง

ควรสร้างชุด acceptance corpus ขนาดเล็กก่อนตัดสินใจ: ใส่บทความที่เป็นรายการล้วน, ย่อหน้าสั้น, โปรโมชันที่เป็นพี่น้องกับเนื้อหา, หน้าแทบว่าง และตัวอย่างที่การไม่ตอบเลยดีกว่าการมีข้อมูลปนเปื้อน ให้คะแนน article recovery, boilerplate leakage และ abstention แยกกัน บนฟิกซ์เจอร์ชุดนี้ Readability เด่นเรื่อง recall, newspaper4k ให้แถวที่สมดุลที่สุด, และ resiliparse เป็นตัวเลือกด้าน latency ที่มีจุดบอดกับเนื้อหาแบบ list; ป้ายเหล่านี้ไม่ควรถูกนำออกนอกลักษณะหน้าที่ทดสอบโดยไม่มีการยืนยันซ้ำ

ถ้าจะให้พูดแบบที่ผมจะบอกคุณจริง ๆ มันแคบกว่านั้นมาก: เอาฟิกซ์เจอร์ไปลองกับลักษณะหน้าเว็บของคุณเองก่อนเลือก เพราะสองในหกตัวมองไม่เห็น testbed ที่ผมเริ่มต้นมา และหนึ่งตัวได้คะแนน recall สมบูรณ์แบบแต่ซ่อนความล้มเหลวทั้งระบบไว้ การเปรียบเทียบในตารางคือจุดเริ่มต้น ไม่ใช่สิ่งทดแทน

ลองใช้ Thunderbit สำหรับการดึงข้อมูลเว็บ Get Started Free

คำถามที่พบบ่อย

ตัวเลขพวกนี้เทียบกับ benchmark ที่เผยแพร่ของแต่ละไลบรารีได้ไหม? ไม่ได้ และผมจะไม่อ้างแบบนั้น นี่คือฟิกซ์เจอร์ที่ควบคุมไว้พร้อมหน่วยสังเคราะห์แต่ติดป้ายกำกับ ดังนั้นทั้ง 6 ตัวเห็น bytes ชุดเดียวกันและการเปรียบเทียบกันเองยุติธรรม ตัวเลขที่ตีพิมพ์อย่าง benchmark การแยกบทความจาก scrapinghub ใช้คอร์ปัสจริง ซึ่งวัดสิ่งที่ต่างและยากกว่า ใช้ตารางนี้เพื่อเทียบทั้ง 6 ตัวนี้กันเอง ไม่ใช่เทียบกับตัวเลขจาก paper

ทำไม leak rate ของ Readability สูงกว่า trafilatura มาก ทั้งที่ทั้งคู่ก็ใช้ DOM เหมือนกัน? เพราะเส้นแบ่งที่แต่ละตัวใช้ไม่เหมือนกัน การรั่ว 3 จาก 4 ครั้งของ Readability คือบล็อกโปรโมชันที่อยู่ในคลาสกลาง ๆ และวางเป็นพี่น้องกับบทความ ซึ่ง heuristic แบบดึงบล็อกข้างเคียงเข้าไปจะมองว่าควรเป็นส่วนของเรื่องเดียวกัน หลายครั้งมันก็ใช่ แต่ในฟิกซ์เจอร์ชุดนี้มันคือโปรโมชัน ส่วน trafilatura เข้มกว่าเวลาตัดสินว่าจะต่อบล็อกไหนเข้าไป และรั่วหน่วยเดียวกันไปหนึ่งครั้ง

ควรเชื่อ precision ของ goose3 กับ jusText ไหม? เชื่อได้แค่เมื่อดูควบคู่กับจำนวนตัวอย่าง ทั้งสองตัวถูกคิดคะแนนบน 10 จาก 11 ฟิกซ์เจอร์ที่มีทั้ง article และ boilerplate เพราะมันคืนค่าว่างในหนึ่งฟิกซ์เจอร์ และฟิกซ์เจอร์ที่ไม่มี output ก็ไม่เข้า numerator หรือ denominator ของอัตราส่วน goose3 ที่ precision 1.0000 นั้นจริงสำหรับหน้าที่มันตอบ ส่วน recall 0.8243 เมื่อคิดครบ 22 ฟิกซ์เจอร์คืออีกครึ่งของความจริงเดียวกัน

threshold ความยาวของ jusText มีความสำคัญบนหน้าเว็บจริงไหม? ขึ้นกับความยาวย่อหน้าของคุณทั้งหมด ข่าวที่มีย่อหน้าละ 300 ตัวอักษรจะข้าม length_high ได้ตั้งแต่ย่อหน้าแรกและทำงานปกติ — นั่นคือเหตุผลที่ jusText คืนข้อความสะอาด 1,190 ตัวอักษรบนหน้าจริงเมื่อใช้ค่า default แต่หน้าที่มีแต่ย่อหน้าสั้น, รายการ, หรือคำโปรยสินค้า อาจไม่ข้ามเลย แล้ว jusText จะคืนค่าว่างแทนคำตอบบางส่วน ตั้งค่าให้ชัดก่อน ไม่ใช่ไปเจอเอาใน production

อะไรที่ไม่ได้ทดสอบในนี้? หน้าเว็บจริงทั้งหมด ไม่มีการทดสอบการดึงข้อมูลหลายภาษา ทั้งที่ stoplist คือจุดขายหลักของ jusText, ไม่มีการวัด memory ภายใต้โหลด และไม่มีหน้าเว็บที่ไม่ใช่บทความเลย — ไม่มี product listing, ไม่มี search results, ไม่มี dashboard นอกจากนี้ยังไม่ได้ทดสอบเรื่อง encoding edge cases และระบบนิเวศ Node กับ Python ถูกเปรียบเทียบกันที่พฤติกรรมของไลบรารี ไม่ใช่ประสิทธิภาพ runtime ดังนั้นตัวเลขระดับมิลลิวินาทีข้ามขอบเขตนั้นควรอ่านเป็นระดับความต่างเชิงลำดับ ไม่ใช่อัตราส่วนที่แม่นยำ

Ke
Ke
CTO ที่ Thunderbit | นักวิทยาศาสตร์ข้อมูลอาวุโสและผู้เชี่ยวชาญด้านแมชชีนเลิร์นนิง ด้วยประสบการณ์เกือบสิบปีในด้านแมชชีนเลิร์นนิงและวิทยาศาสตร์ข้อมูล เคเฉินเป็นศิษย์เก่ามหาวิทยาลัยโคลัมเบีย และอดีตนักวิทยาศาสตร์ข้อมูลอาวุโสที่ Walmart Labs ด้วยความเชี่ยวชาญลึกซึ้งที่ได้รับการยอมรับจากเพื่อนร่วมสายงานใน Python, R, Java และสถิติ เขาจึงแบ่งปันมุมมองที่ผ่านการพิสูจน์มาแล้วในการพัฒนาอัลกอริทึม AI ที่ซับซ้อนจากแนวคิดไปสู่สถาปัตยกรรมระดับใช้งานจริง
สารบัญ
Thunderbit · เอเจนต์ข้อมูลเว็บด้วย AI

ดึงข้อมูลจากทุกหน้าได้ใน คลิกเดียว

ได้รับความไว้วางใจจากผู้ใช้กว่า 250,000+ คน
มีแพ็กเกจใช้ฟรี
จากหน้าเว็บสู่สเปรดชีต
อธิบายสิ่งที่คุณต้องการ — AI Agent ของ Thunderbit จะดึงข้อมูลให้และส่งออกไปยัง Excel, Google Sheets, Airtable หรือ Notion เริ่มใช้ได้ฟรี
Chrome Store Rating
PRODUCT HUNT#1 Product of the Week