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

Avi*_*lax 174 html java parsing

在搜索SO和Google时,我发现有一些Java HTML解析器一直被各方推荐.不幸的是,很难找到有关各种图书馆优势和劣势的任何信息.我希望有些人花了一些时间来比较这些库,并且可以分享他们学到的东西.

这是我见过的:

如果有一个我错过的主要解析器,我也很想知道它的优点和缺点.

谢谢!

Bal*_*usC 222

一般

几乎所有已知的HTML解析器都实现了W3C DOM API(JAXP API的一部分,用于XML处理的Java API),并为您提供了一个org.w3c.dom.Document可供JAXP API直接使用的后端.主要差异通常在所讨论的解析器的功能中找到.对于非正确的HTML("tagsoup"),大多数解析器都在一定程度上宽容和宽容,如JTidy,NekoHTML,TagSoupHtmlCleaner.您通常使用这种HTML解析器来"整理"HTML源代码(例如,用<br>XML有效替换HTML -valid <br />),这样您就可以使用W3C DOM和JAXP API以"通常的方式"遍历它.

唯一跳出来的是HtmlUnitJsoup.

的HtmlUnit

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

Jsoup

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

特别是遍历HTML DOM树是Jsoup的主要优势.与之合作过的人都org.w3c.dom.Document知道使用详细NodeListNodeAPI 遍历DOM会带来多大的痛苦.诚然,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());
}
Run Code Online (Sandbox Code Playgroud)

以下是如何使用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());
}
Run Code Online (Sandbox Code Playgroud)

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

摘要

现在各自的利弊应该足够清楚.如果您只想使用标准的JAXP API来遍历它,那么请转到第一个提到的解析器组.它们中有很多.选择哪一个取决于它提供的功能(如何使HTML清理变得容易?是否有一些监听器/拦截器和特定于标签的清洁器?)和库的稳健性(更新/维护/修复的频率如何? ).如果您想对HTML进行单元测试,那么HtmlUnit就是您的选择.如果您想从HTML中提取特定数据(这通常是现实世界的要求),那么Jsoup就是您的选择.

  • `Jsoup`很好.我试图将它与另一个与`org.w3c.dom.*`API一起使用的模块连接起来.发现Jsoup不遵守`org.w3c.dom.*`合同 (3认同)

Mat*_*nit 13

本文比较了以下解析器的某些方面:

  • NekoHTML
  • JTidy
  • TagSoup
  • HtmlCleaner

它绝不是一个完整的摘要,它是从2008年开始的.但你可能会觉得它很有帮助.


Alo*_*hci 7

将Validator.nu HTML Parser(Java中的HTML5解析算法的实现)添加到列表中.

从好的方面来说,它专门设计用于匹配HTML5,并且是HTML5验证器的核心,因此极有可能将未来浏览器的解析行为与非常高的准确性相匹配.

从负面来看,没有任何浏览器的遗留解析工作与此完全相同,并且HTML5仍处于草案状态,可能会发生变化.

在实践中,这些问题仅影响模糊的角落情况,并且出于所有实际目的,是一种出色的解析器.


MJB*_*MJB 7

我发现Jericho HTML Parser编写得非常好,保持最新(许多解析器都不是),没有依赖关系,并且易于使用.


Ada*_*ent 6

在使用Java中的大多数HTML解析库之后,我将只添加@MJB答案,有一个巨大的pro/con被省略:解析器在输入和输出上保留HTML的格式和不正确性.

当您更改文档时,大多数解析器都会破坏DOM的空格,注释和不正确性,特别是如果它们是类似XML的库.

Jericho是我所知道的唯一一个允许你操纵令人讨厌的HTML同时保留空格格式和HTML的错误(如果有的话)的解析器.