选择标签时jsoup返回标签?

时间:2015-06-03 01:07:15

标签: html jsoup

我是jsoup的新手,可能使用它错了。我打算联系邮件列表,但是jsoup instructs to post here first。我试图从表中选择<td>元素,但返回的第一个元素实际上是<thead>。这是获取给定表的<td>元素的错误方法吗?如果是这样,那么正确的方法是什么?

以下简单代表性问题:

HTML:

<table id="results_table">
    <thead>
        <th>Header1</th>
    </thead>
    <tbody>
        <tr>
            <td>td1</td>
        </tr>
    </tbody>
</table>

测试:

String pageHtml = IOUtils.toString(this.getClass().getResourceAsStream("sample.html"));
Document doc = Jsoup.parse(pageHtml);
Element table = doc.getElementById("results_table");
Elements trs = table.getElementsByTag("tr");

System.out.println("Size: " + trs.size());
System.out.println("First Element: " + trs.get(0).html());
System.out.println("Second Element: " + trs.get(1).html());

收到的输出:

Size: 2
First Element: <th>Header1</th>
Second Element: <td>td1</td>

预期产出:

Size: 1
First Element: <td>td1</td>
//Index out of bounds exception

1 个答案:

答案 0 :(得分:2)

据推测,jsoup在解析HTML文档时会将<th>元素放在自己的<tr>中,从而产生以下DOM:

<table id="results_table">
    <thead>
        <tr>
            <th>Header1</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>td1</td>
        </tr>
    </tbody>
</table>

由于表格单元格必须位于表格行中(这意味着您的源HTML文件无效),我希望任何HTML处理器(尤其是Web浏览器)都能这样做(这在XML模式下不会发生,尽管,jsoup不支持)。

相反,您可以使用doc.select()和CSS选择器来获取<tbody>中的行:

String pageHtml = IOUtils.toString(this.getClass().getResourceAsStream("sample.html"));
Document doc = Jsoup.parse(pageHtml);
Elements trs = doc.select("#results_table tbody tr");

System.out.println("Size: " + trs.size());
System.out.println("First Element: " + trs.get(0).html());
System.out.println("Second Element: " + trs.get(1).html()); // IndexOutOfBoundsException

(您也可以使用一系列getElementsByTag()次调用,但这需要额外的遍历和迭代;使用doc.select()会更加清晰。)

如果您不需要先浏览行,只想直接获取<td>元素,则可以这样做:

String pageHtml = IOUtils.toString(this.getClass().getResourceAsStream("sample.html"));
Document doc = Jsoup.parse(pageHtml);
Element table = doc.getElementById("results_table");
Elements tds = table.getElementsByTag("td");