【问题标题】:Extracting Table Data with JSoup on Yahoo Finance在 Yahoo Finance 上使用 JSoup 提取表数据
【发布时间】:2015-06-22 02:38:26
【问题描述】:

尝试练习使用 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 编写的。

欢迎提出任何建议。

【问题讨论】:

    标签: java html-parsing jsoup


    【解决方案1】:

    编辑后关于您的来源的注释:

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

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

    Elements elems = doc.select("td.yfnc_tablehead1:containsOwn("+sharesOutstanding+") + td.yfnc_tabledata1");
    
    if ( ! elems.isEmpty() ) {
        System.out.println( elems.get(0).owntext() );
    }
    

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

    注意:此答案的先前版本对Elements.select()Element.select() 之间的区别进行了长时间的喋喋不休。事实证明,我完全错了,你的原始版本应该可以工作——如果你纠正了上面的四点。因此,直截了当地记录:Elements 上的 select() 实际上确实会查看每个元素,结果列表可能包含原始列表中与选择匹配的任何元素的后代。对此感到抱歉。

    【讨论】:

    • 谢谢。我试图理解但仍然感到困惑。我引用的表有“tr”元素和“td”元素。此外,当我尝试将上面的“元素”更改为“元素”时,我返回“不兼容的类型错误”。
    • 进行了编辑。希望我越来越近。我仍然没有返回任何东西。
    • 我了解元素/元素的区别。很棒的解释。 ...根据 cmets 和编辑的解释做了更多的编辑。
    • @Nikolas 好吧,现在你的第二次尝试成功了 - 它找到了两次 td,但这可能是因为那里有一个嵌套表。
    • 所以,我把它从它自己的类移到了 Main,现在我看到了。我也明白你两次找到 td 的意思。但是,这是一个巨大的进步,因为现在我明白发生了什么,并且我正在返回一个值。
    猜你喜欢
    • 2023-01-23
    • 1970-01-01
    • 1970-01-01
    • 2021-10-07
    • 2016-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多