【问题标题】:Java HTML Parsing [closed]Java HTML解析[关闭]
【发布时间】:2010-09-19 06:39:51
【问题描述】:

我正在开发一个从网站上抓取数据的应用程序,我想知道我应该如何获取数据。具体来说,我需要包含在许多使用特定 CSS 类的 div 标签中的数据 - 目前(出于测试目的)我只是在检查

div class = "classname"

在 HTML 的每一行中 - 这行得通,但我不禁觉得那里有更好的解决方案。

有什么好方法可以让我给一个类一行 HTML 并有一些很好的方法,比如:

boolean usesClass(String CSSClassname);
String getText();
String getLink();

【问题讨论】:

标签: java html parsing web-scraping


【解决方案1】:

另一个可能对 HTML 处理有用的库是 jsoup。 Jsoup 尝试清理格式错误的 HTML,并允许在 Java 中使用类似标签选择器语法的 jQuery 进行 html 解析。

http://jsoup.org/

【讨论】:

  • 有什么方法不用外接jar吗?
  • @Futuregeek 我曾经使用正则表达式,直到我读到this answer
【解决方案2】:

如前所述,主要问题是 HTML 格式错误,因此必须使用 html 清理器或 HTML-XML 转换器。获得 XML 代码 (XHTML) 后,有很多工具可以处理它。您可以通过一个简单的 SAX 处理程序来获取它,该处理程序只提取您需要的数据,或者任何基于树的方法(DOM、JDOM 等),甚至可以让您修改原始代码。

这是一个示例代码,它使用HTML cleaner 来获取所有使用某个类的 DIV,并打印出其中的所有 Text 内容。

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.htmlcleaner.HtmlCleaner;
import org.htmlcleaner.TagNode;

/**
 * @author Fernando Miguélez Palomo <fernandoDOTmiguelezATgmailDOTcom>
 */
public class TestHtmlParse
{
    static final String className = "tags";
    static final String url = "http://www.stackoverflow.com";

    TagNode rootNode;

    public TestHtmlParse(URL htmlPage) throws IOException
    {
        HtmlCleaner cleaner = new HtmlCleaner();
        rootNode = cleaner.clean(htmlPage);
    }

    List getDivsByClass(String CSSClassname)
    {
        List divList = new ArrayList();

        TagNode divElements[] = rootNode.getElementsByName("div", true);
        for (int i = 0; divElements != null && i < divElements.length; i++)
        {
            String classType = divElements[i].getAttributeByName("class");
            if (classType != null && classType.equals(CSSClassname))
            {
                divList.add(divElements[i]);
            }
        }

        return divList;
    }

    public static void main(String[] args)
    {
        try
        {
            TestHtmlParse thp = new TestHtmlParse(new URL(url));

            List divs = thp.getDivsByClass(className);
            System.out.println("*** Text of DIVs with class '"+className+"' at '"+url+"' ***");
            for (Iterator iterator = divs.iterator(); iterator.hasNext();)
            {
                TagNode divElement = (TagNode) iterator.next();
                System.out.println("Text child nodes of DIV: " + divElement.getText().toString());
            }
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }
}

【讨论】:

    【解决方案3】:

    几年前,我出于同样的目的使用了 JTidy:

    http://jtidy.sourceforge.net/

    "JTidy 是 HTML Tidy 的 Java 端口,是一个 HTML 语法检查器和漂亮的打印机。像它的非 Java 表亲一样,JTidy 可以用作清理格式错误和错误 HTML 的工具。此外,JTidy 提供了一个 DOM正在处理的文档的接口,这有效地使您能够将 JTidy 用作真实世界 HTML 的 DOM 解析器。

    JTidy 是由 Andy Quick 编写的,后来他从维护者的位置上退下来了。现在 JTidy 由一群志愿者维护。

    可以在 JTidy SourceForge 项目页面上找到有关 JTidy 的更多信息。”

    【讨论】:

    • 遗憾的是 jtidy 很慢。
    • JTidy 似乎是一个废弃的项目,几年没更新了。
    【解决方案4】:

    您可能对TagSoup 感兴趣,这是一个能够处理格式错误的 HTML 的 Java HTML 解析器。 XML 解析器只能在格式良好的 XHTML 上工作。

    【讨论】:

      【解决方案5】:

      HTMLParser 项目 (http://htmlparser.sourceforge.net/) 可能是一种可能性。它在处理格式错误的 HTML 方面似乎相当不错。以下 sn-p 应该可以满足您的需要:

      Parser parser = new Parser(htmlInput);
      CssSelectorNodeFilter cssFilter = 
          new CssSelectorNodeFilter("DIV.targetClassName");
      NodeList nodes = parser.parse(cssFilter);
      

      【讨论】:

        【解决方案6】:

        杰里科:http://jericho.htmlparser.net/docs/index.html

        易于使用,支持格式不正确的 HTML,示例很多。

        【讨论】:

          【解决方案7】:

          HTMLUnit 可能会有所帮助。它还可以做更多的事情。

          http://htmlunit.sourceforge.net/1

          【讨论】:

            【解决方案8】:

            我们不要忘记Jerry,它的 jQuery in java:一个快速简洁的 Java 库,可简化 HTML 文档的解析、遍历和操作;包括 css3 选择器的使用。

            例子:

            Jerry doc = jerry(html);
            doc.$("div#jodd p.neat").css("color", "red").addClass("ohmy");
            

            例子:

            doc.form("#myform", new JerryFormHandler() {
                public void onForm(Jerry form, Map<String, String[]> parameters) {
                    // process form and parameters
                }
            });
            

            当然,这些只是一些简单的例子,让你感受一下它的样子。

            【讨论】:

            • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接的答案可能会失效。
            • 谢谢,添加示例。我还没有看到其他大多数 cmets 的示例,所以我遵循了相同的模式。
            • 没问题。它出现在低质量队列中。我的评论是由 SO 自动生成的。
            【解决方案9】:

            nu.validator 项目是一个出色的高性能 HTML 解析器,在正确性方面不会偷工减料。

            Validator.nu HTML 解析器是 HTML5 解析算法的 Java 实现。该解析器旨在作为 XML 解析器的直接替代品,在已经使用 XML 解析器支持 XHTML 1.x 内容并使用 SAX、DOM 或 XOM 与解析器交互的应用程序中工作。为希望执行自己的 IO 并通过脚本支持 document.write() 的应用程序提供了低级功能。解析器核心在 Google Web Toolkit 上编译,可以自动翻译成 C++。 (C++ 翻译功能目前用于移植解析器以在 Gecko 中使用。)

            【讨论】:

              【解决方案10】:

              你也可以使用XWiki HTML Cleaner:

              它使用HTMLCleaner 并对其进行扩展以生成有效的 XHTML 1.1 内容。

              【讨论】:

                【解决方案11】:

                如果您的 HTML 格式正确,您可以轻松地使用 XML 解析器来为您完成这项工作...如果您只是阅读,SAX 将是理想的选择。

                【讨论】:

                • 如果您的 HTML 格式正确。有过吗?
                • 因为我和其他人一起做项目,其中一些是不能创建完美 HTML 的设计师,而其他许多人也没有,当使用诱惑时更是如此。
                • 这是完全错误的,只有 XHTML 可以用 XML 解析器解析。
                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2012-05-25
                • 1970-01-01
                • 2011-01-08
                • 2016-03-23
                • 1970-01-01
                • 2014-01-10
                • 2011-03-08
                相关资源
                最近更新 更多