小编典典

领先的 Java HTML 解析器的优缺点是什么?

all

搜索 SO 和 Google,我发现有一些 Java HTML
解析器,各方一致推荐。不幸的是,很难找到有关各种库的优缺点的任何信息。我希望有些人花了一些时间比较这些库,并可以分享他们学到的东西。

这是我所看到的:

如果我错过了一个主要的解析器,我也很想听听它的优缺点。

谢谢!


阅读 59

收藏
2022-08-16

共1个答案

小编典典

一般的

几乎所有已知的 HTML 解析器都实现了W3C DOM
API
(JAXP API 的一部分,用于 XML 处理的 Java
API)并为您提供了一个org.w3c.dom.Document可供
JAXP API 直接使用的支持。主要差异通常可以在所讨论的解析器的特性中找到。大多数解析器在一定程度上宽容和宽容非格式良好的
HTML(“tagsoup”),例如JTidyNekoHTMLTagSoupHtmlCleaner。您通常使用这种
HTML 解析器来“整理”HTML 源代码(例如,将 HTML-valid 替换为<br>XML-valid <br />),以便您可以使用 W3C
DOM 和 JAXP API“以通常的方式”遍历它。

唯一跳出来的是HtmlUnitJsoup

html单元

HtmlUnit提供了一个完全自己的 API,它使您可以像 Web
浏览器一样以编程方式行事。即输入表单值、单击元素、调用 JavaScript 等。它不仅仅是一个 HTML 解析器。它是一个真正的“无 GUI
网络浏览器”和 HTML 单元测试工具。

Jsoup还提供了完全自己的
API。它使您可以使用类似jQueryCSS
选择器
来选择元素,并提供一个灵活的 API 来遍历 HTML DOM
树以获取感兴趣的元素。

尤其是 HTML DOM 树的遍历是 Jsoup 的主要优势。使用过的人都org.w3c.dom.Document知道使用冗长的 API 遍历 DOM
是多么NodeList痛苦Node。诚然,XPath让生活更轻松,但仍然是另一个学习曲线,最终可能仍然很冗长。

这是一个示例,它使用像 JTidy 这样的“普通”W3C DOM 解析器结合 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());
}

你看得到差别吗?它不仅代码更少,而且如果您已经对 CSS 选择器有一定的经验(例如通过开发网站和/或使用 jQuery),Jsoup 也相对容易掌握。

概括

现在每个人的优缺点应该很清楚了。如果您只想使用标准的 JAXP API 来遍历它,那么请使用第一个提到的解析器组。有很多。选择哪一个取决于它提供的功能(HTML
清理如何让您轻松?是否有一些侦听器/拦截器和特定于标签的清理器?)以及库的健壮性(它多久更新/维护/修复? )。如果您喜欢对 HTML 进行单元测试,那么
HtmlUnit 是您的最佳选择。如果您想从 HTML 中提取特定数据(这通常是现实世界的要求),那么 Jsoup 就是您的最佳选择。

2022-08-16