Jsoup - 提取数据

时间:2014-11-01 05:23:12

标签: java jsoup

假设我有以下html

<table id="tableMain">
  <tr>
    <td class="location">Location A text</td>
  </tr>
  <tr>
   <td>
    <table id="titleList">
     <tr>
      <td class="title">Title A.A</td>
      <td class="date">date</td>
      <td class="time">time</td>
     </tr>
    </table>
    <table id="titleList">
     <tr>
      <td class="title">Title A.B</td>
      <td class="date">date</td>
      <td class="time">time</td>
     </tr>
    </table>
    <table id="titleList">
     <tr>
      <td class="title">Title A.C</td>
      <td class="date">date</td>
      <td class="time">time</td>
     </tr>
    </table>
   </td>
  </tr>

  <tr>
    <td class="location">Location B text</td>
  </tr>
  <tr>
   <td>
    <table id="titleList">
     <tr>
      <td class="title">Title B.A</td>
      <td class="date">date</td>
      <td class="time">time</td>
     </tr>
    </table>
    <table id="titleList">
     <tr>
      <td class="title">Title B.B</td>
      <td class="date">date</td>
      <td class="time">time</td>
     </tr>
    </table>
    <table id="titleList">
     <tr>
      <td class="title">Title B.C</td>
      <td class="date">date</td>
      <td class="time">time</td>
     </tr>
    </table>
   </td>
  </tr>
</table>

有两个位置:位置A和位置B.每个位置都有多个标题列表,其中每个列表包含标题,日期和时间。

我能够提取位置,但我不知道如何提取标题列表并映射到各自的位置。

这是我提取位置的方式:

File input = new File("/home/user/htmlcontent.txt");
Document doc = Jsoup.parse(input, "UTF-8", "http://www.example.com");

Elements elements = doc.select("table#tableMain").select("location");
for (Element e: elements) {
  system.out.println(e.text());
}

1 个答案:

答案 0 :(得分:1)

考虑这个例子:

    Document document = Jsoup.parse(html);

    Elements elements = document.select("#tableMain tr:has(td.location) + tr");

    for (Element element : elements) {
        String location = element.previousElementSibling().select("td.location").text();

        System.out.printf("Current location: '%s'%n", location);

        Elements titleLists = element.select("#titleList > tbody > tr");

        for (Element tr : titleLists) {
            String title = tr.select("td.title").text();
            String date = tr.select("td.date").text();
            String time = tr.select("td.time").text();

            System.out.printf("Title: %s, Date: %s, Time: %s%n", title, date, time);
        }
    }

您可以在此处找到完整代码 - https://gist.github.com/wololock/b0e31cb174123d463e3e

此示例中最重要的部分是用于选择不包含位置信息的行的选择器:

document.select("#tableMain tr:has(td.location) + tr")

为了实现这一目标,我们首先要求tr td.location ... + tr,并且从那时起我们要求兄弟元素#titleList。从这一点开始,我们引用了具有嵌套element.previousElementSibling().select("td.location").text() 表的行。在开始从嵌套表中选择数据之前,您可以使用以下命令提取位置信息:

element.select("#titleList > tbody > tr")

我使用了迭代:

{{1}}

并一次选择单个数据,例如标题,日期,时间。它不是最有效的解决方案,它取决于源html中可能有多少行。虽然针对大量数据进行优化不应该是任何问题。

我希望这会对你有所帮助:)。