领先的Java HTMLparsing器有什么优点和缺点?

searchSO和Google,我发现有几个Java HTMLparsing器一直被各方推荐。 不幸的是,很难find有关各个图书馆的长处和短处的信息。 我希望有些人花了一些比较这些图书馆,并分享他们学到的东西。

这是我所看到的:

  • JTidy
  • NekoHTML
  • jsoup
  • TagSoup

如果有一个我曾经错过的重要parsing器,我也很乐意听到它的优点和缺点。

谢谢!

一般

几乎所有已知的HTMLparsing器都实现了W3C DOM API (JAXP API的一部分,用于XML处理的Java API),并为您提供了一个可供JAXP API直接使用的org.w3c.dom.Document 。 主要的差异通常在parsing器的特征中find。 大多数parsing器在一定程度上是宽容和宽松的,与非格式化的HTML(“tagsoup”),如JTidy , NekoHTML , TagSoup和HtmlCleaner 。 您通常使用这种HTMLparsing器来“整理”HTML源代码(例如,用XML有效的<br />replaceHTML有效的代码),以便您可以使用W3C DOM和JAXP API。

唯一跳出来的是HtmlUnit和Jsoup 。

的HtmlUnit

HtmlUnit提供了一个完全自己的API,它使您能够以编程方式像webbrowser一样行事。 即input表单值,单击元素,调用JavaScript等等。 它不仅仅是一个HTMLparsing器。 这是一个真正的“无GUI网页浏览器”和HTMLunit testing工具。

Jsoup

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

特别是HTML DOM树的遍历是Jsoup的主要优势。 使用org.w3c.dom.Document知道使用详细的NodeListNode API遍历DOM是多么的痛苦。 诚然, XPath使生活变得更加简单,但是,它仍然是另一种学习曲线,最终可能会变得冗长。

下面是一个例子,它使用像JTidy这样的“简单”W3C DOMparsing器,结合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()); } 

你看到差异吗? 这不仅仅是代码less,但是如果你已经有了CSSselect器的经验(比如开发网站和/或使用jQuery),Jsoup也相对容易掌握。

概要

每个人的利弊现在应该清楚了。 如果您只是想使用标准的JAXP API来遍历它,那么请参阅第一组提到的parsing器。 他们中有很多人。 select哪一个取决于它提供的function(HTML清理是如何轻松实现的?是否有一些监听器/拦截器和特定标签的清理器?)和库的健壮性(多久更新一次/维护/修复? )。 如果你想unit testingHTML,那么HtmlUnit是要走的路。 如果你喜欢从HTML中提取特定的数据(这往往是现实世界的要求),那么Jsoup就是要走的路。

本文比较以下parsing器的某些方面:

  • NekoHTML
  • JTidy
  • TagSoup
  • HtmlCleaner

这绝不是一个完整的总结,它是从2008年开始的。但是你可能会觉得它有帮助。

将validator.nu HTML Parser添加到您的列表中,将Java中的HTML5parsingalgorithm的实现添加到列表中。

另一方面,它是专门为匹配HTML5而devise的,它是HTML5validation程序的核心,极有可能以非常高的准确度匹配未来浏览器的parsing行为。

不利的一面是,浏览器的传统parsing并不像这样,HTML5仍然在草案中,可能会有所变化。

在实践中,这样的问题只影响不明确的angular落案例,并且实际上是一个优秀的parsing器。

我发现Jericho HTML Parser写得很好,保持最新(许多parsing器不是),没有依赖关系,并且易于使用。

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

这是大多数parsing器,当你改变文档将会消除DOM的空白,注释和不正确,特别是如果它们是XML类库。

Jericho是我所知道的唯一一个parsing器,它允许您在保留空白格式和HTML(如果有的话)不正确的情况下操作讨厌的HTML。

另外两个选项是HTMLCleaner和HTMLParser 。

我已经尝试了大部分parsing器,用于我一直在开发的爬虫/数据提取框架。 我使用HTMLCleaner进行大量的数据提取工作。 这是因为它支持具有名称空间的HTML,XHTML,HTML 5的合理的现代方言,它支持DOM,因此可以将其与Java内置的XPath实现结合使用 。

使用HTMLCleaner比使用其他一些parsing器要容易得多:例如,JSoup支持类似DOM的接口,而不是DOM,所以需要一些程序集 。 杰里科有一个SAX线接口,所以需要一些工作,虽然Sujit Pal有一个很好的描述如何做到这一点,但最终HTMLCleaner只是工作得更好。

我还使用HTMLParser和Jericho进行表提取任务,取代了使用Perl的libhtml-tableextract-perl编写的一些代码。 我使用HTMLParser过滤表格的HTML,然后使用杰里科parsing它。 我同意MJB和Adam的意见,Jericho在某些情况下是好的,因为它保留了底层的HTML。 它有一种非标准的SAX接口,所以XPath处理HTMLCleaner比较好。

在Java中parsingHTML是一个令人惊讶的难题,因为所有的parsing器似乎都在某些types的格式错误的HTML内容上挣扎。