从Java

时间:2015-10-06 20:12:47

标签: java web-scraping html-table jsoup

为了我将来的便利,我决定尝试创建一个Java程序,它可以在我的计算机上获取目录和电视节目的Wikipedia条目的URL,然后继续使用该节目重命名该目录中的所有文件姓名," S x E y "和剧集的标题。虽然我相信我有重命名文件的工作代码,但我坚持的一件事就是填充包含剧集名称的数组。虽然这可以手动完成,但这首先会消除程序的重点,所以我希望能够从互联网上获取信息。

现在有问题的电视节目是Arrow,我现在想要获得第2季的剧集名称。我一直试图修改this jsoup教程来访问表,希望一旦它开始工作就缩小到所需的表。我修改后的代码供参考:

package tablescraper;

import java.io.IOException;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

public class TableScraper {

public static void main(String[] args) {
    try {
        Document doc = Jsoup.connect("http://en.wikipedia.org/wiki/List_of_Arrow_episodes").get();
        Elements trs = doc.select("table.wikitable tr");

        //remove header row
        trs.remove(0);

        for (Element tr : trs) {

            Elements tds = tr.getElementsByTag("td.summary");
            Element td = tds.first();
            System.out.println("Episode: " + td.toString());
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}
}

在目前状态下,我java.lang.NullPointerException遇到System.out.println("Episode: " + td.toString());。我试图在.summary语句中添加getElementsByTag,希望只能选出具有"摘要"的元素。上课,这是我需要的。

到目前为止,我的方法是否出错了?我做过的任何明显遗漏?您会注意到表格中的每一行都包含一个总结该剧集的段落 - 这种格式的变化是问题的一部分吗?如果我像现在一样迭代每个表行,它会变成一个问题吗?展望未来,我如何能够区分页面上的每个表格?如果没有办法区分这些特定来源,那么这不是世界末日,如果有必要,我可以简单地列出所有剧集和然后根据所需的剧集编号将其缩小到一系列条目。

1 个答案:

答案 0 :(得分:1)

页面中必须有包含wikitable类的表格,其中包含td个元素,而不包含summary个字段。

因此,在输出td

之前插入空值是个好主意
Elements tds = tr.getElementsByTag("td.summary");
Element td = tds.first();
if (td != null)
    System.out.println("Episode: " + td.toString());

然后

Elements tds = tr.getElementsByTag("td.summary");

永远不会返回非空列表,因为没有带有标记td.summary的元素。再次使用select查找与选择器td.summary匹配的后代:

Elements tds = tr.select("td.summary");

最后要打印出这一集(这是td元素的文字内容),请不要使用td.toString(),而是使用td.text()

System.out.println("Episode: " + td.text());