2015-10-06 45 views
0

为了我自己的未来便利,我决定尝试创建一个Java程序,可以在我的计算机上使用目录,并在电视节目中使用维基百科条目的URL,然后重命名所有显示名称为“S x E y”的该目录中的文件和该集的标题。虽然我相信我有工作代码来重命名文件,但我坚持的一件事是填充包含剧集名称的数组。虽然这可以手动完成,但首先会消除程序的重点,所以我希望能够从互联网上获取信息。从Java中提取维基百科表中的特定元素

现在有问题的电视节目是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(); 
    } 
} 
} 

在它是我在System.out.println("Episode: " + td.toString());面临java.lang.NullPointerException当前状态。我试图在getElementsByTag声明中添加.summary,希望只能挑选出具有“摘要”类的元素,这是我需要的。

到目前为止,我在方法中犯了错误吗?我所做的任何明显的遗漏?你会注意到表格中的每一行都包含了一段总结了这一集的段落 - 这种格式变化是问题的一部分吗?如果我像现在一样迭代每个表格行,它会不会成为问题?展望未来,我将如何区分网页上的每个表格?如果没有办法区分他们之间的这个特定的来源,那么这不是世界末日,因为如果有必要,我可以简单地采取所有事件的列表,然后将其减少到选定范围的条目在需要的情节数字上。

+0

你怎么知道它刚从第二季回来?这个'doc.select(“table.wikitable td.summary”)'应该返回来自所有季节的所有剧集的名字。 – FirstOne

+0

我不知道它是什么,但那是我的最终目标。现在我想它会查看页面上包含指定标签的所有表格,但目前还没有运气。随着你的改变,我将如何输出该剧集列表?我会调整'tr.getElementsByTag'到'tr.getAllElements'吗?我对这个图书馆并不熟悉,但是列出所有情节会让我更接近我的目标。 –

回答

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()); 
+0

好的,我做了这个改变,现在错误消失了,但是代码没有返回结果。是否有可能仅查看行中的第一个项目,然后在看到它不是类“摘要”时移动到下一行? –

+0

@SimonB'tr.getElementsByTag(“td.summary”)'有问题。看到我编辑的帖子, – wero

+0

啊我现在看到了。有了这个改变,程序现在输出整个html的输入,例如输出的第二行是Episode:“荣誉您的父亲”'。不包括“Episode:”位,我想我现在可以使用子字符串在'>“'和<”之后删除所有内容,对吧?第一行不遵循这种格式,但我可以稍后再纠正。 –