如何在Java中剖析HTML页面,以挑选某些元素


How to dissect an HTML page in Java, to pick out certain elements?

由于我不想讨论这个问题的原因,我有一个Java类,它发布HTML表单,并读取响应。

我得到的一小段回复是:

<div class="main_box">
  <table width="100%" border="0" cellspacing="4" cellpadding="4" class='results'>
    <tr>
        <td colspan="3" class="title">Free Car ID Check Results</td>
    </tr>
    <tr>
        <td class='title' width='34%'>Vehicle Registration Number</td>
        <td width="43%">ABC123</td>
        <td width="23%" rowspan="4" valign="top"><p align="center"><img src="/media/FORD.jpg" alt="FORD" /></p>
        <p>      </p></td>
    </tr>
    <tr>
        <td  class='title'>Make</td>
        <td>FORD</td>
    </tr>
    <tr>
        <td class='title'>Model</td>
        <td>ESCORT</td>
    </tr>
    <tr>
        <td class='title'>Colour</td>
        <td>BLUE</td>
    </tr>
  </table>
</div>

从中提取makemodelcolour的最简单、稳健的方法是什么?这只是我正在阅读的输入流的一小部分,我不能保证它之外的HTML元素会保持不变,因为网页中可能会发生变化。

感谢

使用像JSoup这样的HTML解析器。它允许您轻松阅读文档并选择元素。

例如

Document doc = Jsoup.connect("http://url").get();
Elements elements = doc.select("div[class=main_box] td[class=title]");
for (Element anElement : elements) {
    // Real treatment here
    System.out.print(anElement.text());
    System.out.println(": "+anElement.nextElementSibling().text());
}

我用来从网站获取数据的"简单"方法是仔细分析它们的HTML,然后只搜索一些与众不同的东西,比如">Make<",然后搜索下一个"<td>",然后搜索第二个"</td>",并获取介于两者之间的内容。

如果它们有任何转义字符,如果有多个">Make<"实例等,或者当它们将来更改输出时,这显然是高度不健壮的。

然而,具有高级XHTML解析器等的"健壮"方法通常假设网站正在提供格式良好的HTML或XHTML。根据我的经验,没有人提供格式良好的HTML-(嗯,不多…可以说,我的快速而肮脏的方法比使用真正的解析器更健壮

p.s.-对于那些将用真正的解析器提供真正答案的SO专家,请描述他们是如何处理格式错误的HTML的,因为我在这方面遇到了真正的问题。。。

在一条评论中,我向@his承诺,我会尝试JSoup,并将其与我的"只需搜索>Make<"风格的代码(这是我写的一个名为HTMLGrabber的小类中的代码)进行比较。

首先,我发现JSoup很容易使用,它至少处理了我测试过的一个糟糕的HTML文件(还有三个要测试)。生成的代码在长度上与HTMLGrabber代码相似。稍微长一点,但还不错。HTMLGrabber并不像我记忆中那么简单,因为我添加了一些unscape/escape代码,对Attributes的小支持等等

如果网站发生巨大变化,任何"抓取"方法最终都是不可靠的

HTMLGrabber风格代码的"优势"在于,您可以直接根据内容进行搜索。在汽车代码示例中,您可能会先跳到"Free car ID Check Results",然后查找">Make<",然后是"<td>",并在下一个之前获取文本"</td>",产生"FORD"。然后类似于">型号<"answers">颜色<"。为什么这可能是一种"优势"?如果HTML的结构发生变化,例如它不再在表中,或者添加了更多行,这种方法可能仍然有效。即,面对HTML中的结构变化,它"更健壮"(但仍远未达到完美)。

JSoup/"真正的解析器"方法的优点是它可以处理愚蠢的转义字符,而且,通常(至少,我会如何编码它,YMMV),你会遵循HTML的结构,至少在一定程度上,找到你想要的东西。在car示例中,您将查找类为"main_box"的div元素,然后查找表,然后查找行等。这种方法在内容更改时更加稳健。例如,当你的网站被买断,"免费汽车身份证检查结果"更改为"Facebook汽车身份证检测结果"时,这仍然有效。(请注意,没有什么是完美的,如果"main_box"改为"primary_box",你就会遇到麻烦)。

我不知道在人们抓取的随机网站中,内容或结构的变化是否更频繁。有人在那里有任何统计数据或经验吗?

总之,我发现JSoup"足够简单",我将在未来大部分时间使用它,因为我怀疑它总体上更健壮。但是,对于许多网站来说,"直接获取"的方法可能更为优越。

附录对于我的两个网页,HTML是如此混乱,以至于即使Jsoup设法解析了它,但使用Jsoup遍历DOM被证明是如此困难,以至于我坚持使用快速和肮脏的方法。

试试这个"http://developer.yahoo.com/dotnet/howto-xml_vb.html"它是微软的语言,但如果你愿意从一种语言翻译成另一种语言,它是有用的。祝你好运