如何用Java剖析HTML页面,挑选出某些元素?

时间:2012-02-02 00:05:08

标签: java php forms http post

由于我不想为了这个问题的目的而进入的原因,我有一个发布HTML表单的Java类,并读取响应。

我得到的一小部分答案是:

<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元素将保持不变,就像在网页中可能会改变一样。

由于

4 个答案:

答案 0 :(得分:2)

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

E.g。

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());
}

答案 1 :(得分:0)

我用来从网站上获取数据的“简单”方法是仔细分析他们的HTML,然后只搜索与">Make<"类似的内容,然后搜索下一个"<td>" ,然后是下一个"</td>",并抓住它们之间的内容。

如果它们有任何转义字符,如果有多个“&gt; Make&lt;”等实例,或者当它们将来更改输出时,这显然非常不健壮。

然而,使用花哨的XHTML解析器等的“健壮”方法通常假设该网站正在服务于格式良好的HTML或XHTML 。根据我的经验, nobody服务于格式良好的HTML 。 :-(嗯,不是很多......可以说,我的快速和肮脏的方式比使用真正的解析器更强大。

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

答案 2 :(得分:0)

在评论中,我向@his承诺我会尝试使用JSoup并将其与我更加hacky的比较“只搜索&gt; Make&lt;”样式代码(我写的一个小类,叫做HTMLGrabber。)

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

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

HTMLGrabber样式代码的“优点”是您直接根据内容进行搜索。在汽车代码示例中,您可能首先跳到“免费车辆ID检查结果”,然后查找“&gt;生成&lt;”,然后查找"<td>"并在下一个之前抓取文本 "</td>",产生“福特”。然后类似于“&gt;模型&lt;”和“&gt;颜色&lt;”。为什么这可能是“优势”?如果HTML的结构发生变化,例如它不再在表中,或者添加更多行,这种方法可能仍然有效。即,面对HTML中的结构变化,它“更强大”(但仍然远非完美)。

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

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

总之,我发现JSoup“足够简单”,我将来大部分时间都会使用它,因为我怀疑它通常更强大。但是,对于许多网站来说,“只是抓住它”的方法可能会更好。

ADDENDUM对于我的两个网页,HTML是如此混乱,即使Jsoup设法解析它,使用Jsoup通过DOM来证明是如此困难,以至于我坚持使用快速和脏。 / p>

答案 3 :(得分:-1)

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