ข้อดีและข้อเสียของตัวแยกวิเคราะห์ Java HTML ชั้นนำคืออะไร [ปิด]


175

กำลังค้นหา SO และ Google ฉันพบว่ามีตัวแยกวิเคราะห์ HTML HTML บางส่วนที่ได้รับการแนะนำอย่างสม่ำเสมอจากหลายฝ่าย น่าเสียดายที่มันยากที่จะหาข้อมูลเกี่ยวกับจุดแข็งและจุดอ่อนของห้องสมุดต่างๆ ฉันหวังว่าบางคนใช้เวลาเปรียบเทียบห้องสมุดเหล่านี้และสามารถแบ่งปันสิ่งที่ได้เรียนรู้

นี่คือสิ่งที่ฉันเห็น:

และถ้ามีผู้แยกวิเคราะห์รายใหญ่ที่ฉันพลาดไปฉันก็อยากฟังเกี่ยวกับข้อดีและข้อเสียของมันเช่นกัน

ขอบคุณ!

คำตอบ:


223

ทั่วไป

ตัวแยกวิเคราะห์ HTML ที่รู้จักกันเกือบทั้งหมดใช้W3C DOM API (ส่วนหนึ่งของ JAXP API, Java API สำหรับการประมวลผล XML) และให้การorg.w3c.dom.Documentสนับสนุนที่พร้อมใช้งานโดยตรงโดย JAXP API ความแตกต่างที่สำคัญมักจะพบได้ในคุณสมบัติของ parser ที่เป็นปัญหา parsers ส่วนใหญ่อยู่กับการให้อภัยในระดับหนึ่งและผ่อนปรนกับไม่ใช่ wellformed HTML ( "tagsoup") เช่นJTidy , NekoHTML , TagSoupและHtmlCleaner คุณมักจะใช้โปรแกรมแยกวิเคราะห์ HTML ประเภทนี้เพื่อ "จัดระเบียบ" ซอร์ส HTML (เช่นแทนที่ HTML- ใช้ได้<br>โดยใช้ XML ได้<br />) เพื่อให้คุณสามารถสำรวจ "วิธีปกติ" โดยใช้ W3C DOM และ JAXP API

คนเดียวที่กระโดดออกมาเป็นHtmlUnitและJsoup

HtmlUnit

HtmlUnitให้ API ของตัวเองอย่างสมบูรณ์ซึ่งช่วยให้คุณสามารถทำตัวเหมือนเว็บเบราว์เซอร์แบบเป็นโปรแกรม เช่นป้อนค่าแบบฟอร์มองค์ประกอบคลิกเรียกใช้ JavaScript และอื่น ๆ มันเป็นตัวแยกวิเคราะห์ HTML มากกว่าอย่างเดียว เป็นเครื่องมือทดสอบเว็บเบราเซอร์ GUI น้อยกว่าและ HTML

Jsoup

Jsoupยังมี API ของตัวเองอย่างสมบูรณ์ มันทำให้คุณมีความเป็นไปได้ในการเลือกองค์ประกอบโดยใช้ตัวเลือก CSS ที่เหมือนกันของjQueryและมี API ที่ลื่นไหลเพื่อสำรวจทรี HTML DOM เพื่อรับองค์ประกอบที่น่าสนใจ

โดยเฉพาะอย่างยิ่งการข้ามผ่านของโครงสร้าง HTML DOM เป็นจุดแข็งหลักของ Jsoup คนที่ได้ทำงานด้วยorg.w3c.dom.Documentรู้ว่ามันเจ็บปวดอะไรบ้างที่จะสำรวจ DOM โดยใช้ verbose NodeListและNodeAPI จริงXPathทำให้ชีวิตง่ายขึ้น แต่ถึงกระนั้นก็เป็นอีกหนึ่งช่วงการเรียนรู้และสามารถจบลงด้วยการพูดอย่างละเอียด

นี่คือตัวอย่างที่ใช้ตัวแยกวิเคราะห์ DOM "ธรรมดา" W3C เช่น JTidy ร่วมกับ XPath เพื่อแยกย่อหน้าแรกของคำถามของคุณและชื่อของผู้ตอบคำถามทั้งหมด (ฉันใช้ XPath เพราะไม่มีรหัสจำเป็นต้องรวบรวมข้อมูลที่น่าสนใจ มิฉะนั้นจะโตขึ้นเป็น 10 เท่าโดยไม่ต้องเขียนวิธีการยูทิลิตี้ / ผู้ช่วย)

String url = "http://stackoverflow.com/questions/3152138";
Document document = new Tidy().parseDOM(new URL(url).openStream(), null);
XPath xpath = XPathFactory.newInstance().newXPath();
  
Node question = (Node) xpath.compile("//*[@id='question']//*[contains(@class,'post-text')]//p[1]").evaluate(document, XPathConstants.NODE);
System.out.println("Question: " + question.getFirstChild().getNodeValue());

NodeList answerers = (NodeList) xpath.compile("//*[@id='answers']//*[contains(@class,'user-details')]//a[1]").evaluate(document, XPathConstants.NODESET);
for (int i = 0; i < answerers.getLength(); i++) {
    System.out.println("Answerer: " + answerers.item(i).getFirstChild().getNodeValue());
}

และนี่คือตัวอย่างวิธีทำสิ่งเดียวกันกับ Jsoup:

String url = "http://stackoverflow.com/questions/3152138";
Document document = Jsoup.connect(url).get();

Element question = document.select("#question .post-text p").first();
System.out.println("Question: " + question.text());

Elements answerers = document.select("#answers .user-details a");
for (Element answerer : answerers) {
    System.out.println("Answerer: " + answerer.text());
}

คุณเห็นความแตกต่างหรือไม่ มันไม่ได้เป็นเพียงรหัสน้อยกว่า แต่ Jsoup ยังเข้าใจง่ายหากคุณมีประสบการณ์ปานกลางกับตัวเลือก CSS (เช่นการพัฒนาเว็บไซต์และ / หรือการใช้ jQuery)

สรุป

ข้อดีและข้อเสียของแต่ละคนควรชัดเจนเพียงพอแล้ว หากคุณเพียงต้องการใช้ JAXP API มาตรฐานเพื่อสำรวจมันให้ไปที่กลุ่มตัวแยกวิเคราะห์ที่กล่าวถึงครั้งแรก มีสวยมากของพวกเขา ตัวเลือกใดที่จะเลือกขึ้นอยู่กับคุณลักษณะที่มีให้ (การล้าง HTML ทำได้ง่ายสำหรับคุณมีผู้ฟัง / ตัวดักจับและตัวทำความสะอาดแท็กเฉพาะหรือไม่) และความทนทานของไลบรารี (ปรับปรุงบ่อยครั้ง / แก้ไข / คงที่บ่อยแค่ไหน) ) หากคุณต้องการทดสอบหน่วย HTML แล้ว HtmlUnit เป็นวิธีที่จะไป หากคุณต้องการดึงข้อมูลเฉพาะจาก HTML (ซึ่งมากกว่าความต้องการของโลกแห่งความเป็นจริง) Jsoup เป็นวิธีที่จะดำเนินการ


มีโปร / คอนขนาดใหญ่ที่ละเว้นอยู่ที่นี่: Jericho เป็น parser เดียวที่ฉันรู้ว่าช่วยให้คุณจัดการ HTML ที่น่ารังเกียจในขณะที่รักษารูปแบบช่องว่างและความถูกต้องของ HTML (ถ้ามี)
Adam Gent

3
Jsoupดี. ฉันพยายามเชื่อมต่อกับโมดูลอื่นที่ทำงานกับorg.w3c.dom.*API พบว่า Jsoup ไม่ปฏิบัติตามorg.w3c.dom.*สัญญา
Thamme Gowda

13

บทความนี้เปรียบเทียบบางแง่มุมของตัวแยกวิเคราะห์ต่อไปนี้:

  • NekoHTML
  • JTidy
  • TagSoup
  • HtmlCleaner

มันไม่ได้เป็นบทสรุปที่สมบูรณ์และมาจากปี 2008 แต่คุณอาจพบว่ามีประโยชน์


นี่คือคำตอบสำหรับลิงค์เท่านั้น คุณสามารถเพิ่มรายละเอียดที่เกี่ยวข้องได้ที่นี่?
Reinstate Monica - ไม่ใช่

7

เพิ่มvalidator.nu HTML Parserซึ่งเป็นการนำอัลกอริทึมการแยกวิเคราะห์ HTML5 ใน Java ไปยังรายการของคุณ

ในด้านบวกมันถูกออกแบบมาโดยเฉพาะเพื่อให้ตรงกับ HTML5 และเป็นหัวใจสำคัญของเครื่องมือตรวจสอบ HTML5 ดังนั้นจึงมีความเป็นไปได้สูงที่จะจับคู่พฤติกรรมการแยกวิเคราะห์ของเบราว์เซอร์ในอนาคตกับความแม่นยำระดับสูงมาก

ด้านลบไม่มีการแยกวิเคราะห์แบบดั้งเดิมของเบราว์เซอร์ที่ทำงานแบบนี้และ HTML5 ยังคงอยู่ในรูปแบบร่างอาจมีการเปลี่ยนแปลง

ในทางปฏิบัติปัญหาดังกล่าวมีผลเฉพาะกับมุมที่คลุมเครือเท่านั้นและเพื่อวัตถุประสงค์ในทางปฏิบัติทั้งหมดตัวแยกวิเคราะห์ที่ยอดเยี่ยม


7

ฉันพบJericho HTML Parser เป็นอย่างดีเขียนเก็บไว้ทันสมัย ​​(ซึ่ง parsers จำนวนมากไม่ได้) ไม่มีการอ้างอิงและใช้งานง่าย


6

ฉันจะเพิ่มคำตอบ @MJB หลังจากทำงานกับห้องสมุดการแยกวิเคราะห์ HTML ใน Java ส่วนใหญ่มีการแยก / pro ที่ใหญ่: parsers ที่รักษารูปแบบและความไม่ถูกต้องของ HTML ในอินพุตและเอาต์พุต

นั่นคือตัวแยกวิเคราะห์ส่วนใหญ่เมื่อคุณเปลี่ยนเอกสารจะทำให้ช่องว่างความคิดเห็นและความไม่ถูกต้องของ DOM หายไปโดยเฉพาะอย่างยิ่งหากเป็น XML เช่นไลบรารี่

Jerichoเป็น parser เดียวที่ฉันรู้ว่าช่วยให้คุณสามารถจัดการ HTML ที่น่ารังเกียจในขณะที่รักษาการจัดรูปแบบช่องว่างและความไม่ถูกต้องของ HTML (ถ้ามี)


3

สองตัวเลือกอื่น ๆHTMLCleanerและHTMLParser

ฉันได้ลองใช้ตัวแยกวิเคราะห์ส่วนใหญ่ที่นี่เพื่อหากรอบการทำงานของตัวแยกข้อมูล / ตัวรวบรวมข้อมูลที่ฉันพัฒนาขึ้นมา ฉันใช้ HTMLCleaner สำหรับงานสกัดข้อมูลจำนวนมาก นี้เป็นเพราะสนับสนุนภาษาที่ทันสมัยพอสมควรของ HTML, XHTML, HTML 5 กับ namespaces และสนับสนุน DOM ดังนั้นจึงเป็นไปได้ที่จะใช้มันกับ Java สร้างขึ้นในการดำเนินงานของ

การทำเช่นนี้ทำได้ง่ายกว่าด้วย HTMLCleaner มากกว่าตัวแยกวิเคราะห์อื่น ๆ : ตัวอย่างเช่น JSoup รองรับ DOM เช่นอินเตอร์เฟสแทนที่จะเป็น DOM ดังนั้นจึงจำเป็นต้องใช้แอสเซมบลีบางตัว Jericho มีอินเตอร์เฟซ SAX-line ดังนั้นจึงต้องใช้งานอีกครั้งแม้ว่าSujit Pal จะมีคำอธิบายที่ดีเกี่ยวกับวิธีการทำเช่นนี้แต่ในที่สุด HTMLCleaner ก็ทำงานได้ดีขึ้น

ฉันยังใช้ HTMLParser และเจริโคสำหรับงานสกัดตารางซึ่งแทนที่โค้ดบางส่วนที่เขียนโดยใช้ Perl ของlibhtml-tableextract-Perl ฉันใช้ HTMLParser เพื่อกรอง HTML สำหรับตารางจากนั้นใช้ Jericho เพื่อแยกวิเคราะห์ ฉันเห็นด้วยกับความเห็นของ MJB และอดัมว่า Jericho นั้นดีในบางกรณีเพราะมันรักษา HTML พื้นฐานไว้ มันมีอินเตอร์เฟส SAX ที่ไม่ได้มาตรฐานดังนั้นสำหรับการประมวลผล XPath HTMLCleaner จะดีกว่า

การแยก HTML ใน Java เป็นปัญหาที่ยากอย่างน่าประหลาดใจเนื่องจาก parsers ทั้งหมดดูเหมือนจะต่อสู้กับเนื้อหา HTML ที่มีรูปแบบไม่ถูกต้อง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.