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

通过搜索SO和Google,我发现有几个Java HTML解析器一直被各方推荐。 不幸的是,很难找到任何有关各个图书馆的长处和短处的信息。 我希望有些人花了一些时间比较这些图书馆,并分享他们学到的东西。

以下是我所看到的:

  • JTidy
  • NekoHTML
  • jsoup
  • TagSoup
  • 如果有一个我曾经错过的重要解析器,我也很乐意听到它的优点和缺点。

    谢谢!


    一般

    几乎所有已知的HTML解析器都实现了W3C DOM API(JAXP API的一部分,用于XML处理的Java API),并为您提供了一个可供JAXP API直接使用的org.w3c.dom.Document 。 主要的区别通常在解析器的功能中找到。 大多数解析器在一定程度上都是对非格式化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。 它使您可以使用类似jQuery的CSS选择器来选择元素,并提供一个灵活的API来遍历HTML DOM树以获取感兴趣的元素。

    特别是遍历HTML DOM树是Jsoup的主要优势。 使用org.w3c.dom.Document知道使用详细的NodeListNode API遍历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());
    }
    

    下面是一个如何与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就是要走的路。


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

  • NekoHTML
  • JTidy
  • TagSoup
  • HtmlCleaner
  • 这绝不是一个完整的总结,它是从2008年开始的。但是你可能会发现它有帮助。


    将validator.nu HTML Parser添加到您的列表中,将Java中的HTML5解析算法的实现添加到列表中。

    另一方面,它专为匹配HTML5而设计,并且是HTML5验证程序的核心,极有可能以非常高的准确度匹配未来浏览器的解析行为。

    不利的一面是,浏览器的传统解析并不完全像这样,HTML5仍处于草案中,可能会发生变化。

    在实践中,这些问题只会影响不明确的角落案例,并且适用于所有实际目的,是一个出色的解析器。

    链接地址: http://www.djcxy.com/p/22041.html

    上一篇: What are the pros and cons of the leading Java HTML parsers?

    下一篇: Authentication tokens on REST