使用Yahoo Finance上的JSoup提取表数据

时间:2015-06-20 17:07:09

标签: java html-parsing jsoup

尝试使用JSoup练习从表中提取数据。无法弄清楚为什么我不能从

中拉出“股票优秀”字段

https://finance.yahoo.com/q/ks?s=AAPL+Key+Statistics

以下两次尝试's'是AAPL:

public class YahooStatistics {
String sharesOutstanding = "Shares Outstanding:";

public YahooStatistics(String s)    {
    String keyStatisticsURL = ("https://finance.yahoo.com/q/ks?s="+s+"+Key+Statistics");

//Attempt 1       
    try {
        Document doc = Jsoup.connect(keyStatisticsURL).get();

        for (Element table : doc.select("table.yfnc_datamodoutline1"))  {
            for (Element row : table.select("tr"))  {
                Elements tds = row.select("td");
                for (Element td : tds.select(sharesOutstanding)) {
                    System.out.println(td.ownText());
                }
            }
        }
    }
    catch (IOException ex)   {
        ex.printStackTrace();
    }

//Attempt 2

    try {
    Document doc = Jsoup.connect(keyStatisticsURL).get();

        for (Element table : doc.select("table.yfnc_datamodoutline1"))    {
            for (Element row : table.select("tr"))   {
                Elements tds = row.select("td");
                for (int j = 0; j < tds.size() - 1; j++) {
                    Element td = tds.get(j);
                    if ((td.ownText()).equals(sharesOutstanding)) {
                    System.out.println(tds.get(j+1).ownText());
                    }
                }
            }
        }
    }
    catch(IOException ex)   {
        ex.printStackTrace();
    }

尝试返回:建立成功而没有别的。

我在我的浏览器上禁用了JavaScript并且表格仍然显示,所以我假设这不是用JavaScript编写的,而是HTML。

任何建议都表示赞赏。

1 个答案:

答案 0 :(得分:3)

编辑后有关您的来源的说明:

  • 您应该比较ownText()而不是text()text()为您提供所有元素及其所有子元素的组合文本。在这种情况下,元素包含Shares Outstanding<font size="-1"><sup>5</sup></font>:,因此其组合文本为"Shares Outstanding5:"。如果您使用ownText,则只会"Shares Outstanding:"
  • 请注意冒号(:)。相应地更新sharesOutstanding中的值。
  • 您传递的是错误的网址。 +后面应该有AAPL
  • 您当前的查询(至少是第二次尝试)返回元素两次,因为有一个嵌套表,因此它会找到两次TD。

您可以在找到匹配项后中断循环,返回原始版本(如上所示进行更正) - 请参阅注释 - 或者您可以尝试使用仅匹配一次的更复杂的查询:

Elements elems = doc.select("td.yfnc_tablehead1:containsOwn("+sharesOutstanding+") + td.yfnc_tabledata1");

if ( ! elems.isEmpty() ) {
    System.out.println( elems.get(0).owntext() );
}

此选择器为您提供了类td的所有yfnc_tabledata1元素,其前一个兄弟是一个td元素,其类为yfnc_tablehead1且其自己的文本包含“突出的股票:”字符串。这应该基本上选择你需要的确切TD。

注意:此答案的先前版本对Elements.select()Element.select()之间的差异进行了长时间的喋喋不休。事实证明,我错了,原来的版本应该有效 - 如果你已经纠正了上述四点。所以要直接设置记录:select()上的Elements实际上会查看每个元素,结果列表可能包含原始列表中与选择匹配的任何元素的后代。对不起。