在 Yahoo Finance 上使用 JSoup 提取 Table 数据
Extracting Table Data with JSoup on Yahoo Finance
尝试练习使用 JSoup 从 table 中提取数据。无法弄清楚为什么我不能从
中提取 "Shares Outstanding" 字段
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();
}
尝试 return:构建成功,仅此而已。
我在我的浏览器上禁用了 JavaScript 并且 table 仍然显示,所以我假设这不是写在 JavaScript 而是 HTML.
如有任何建议,我们将不胜感激。
编辑后关于您的来源的说明:
- 你应该比较
ownText()
而不是 text()
。 text()
为您提供所有元素及其所有子元素的组合文本。在本例中,元素包含 Shares Outstanding<font size="-1"><sup>5</sup></font>:
,因此其组合文本为 "Shares Outstanding5:"
。如果您使用 ownText
,它将只是 "Shares Outstanding:"
。
- 注意冒号 (
:
)。相应地更新 sharesOutstanding
中的值。
- 你传错了URL。
AAPL
. 后面应该有一个 +
- 您当前的查询(至少是第二次尝试)返回元素两次,因为有一个嵌套 table 所以它找到了两次 TD。
您可以在找到匹配项后中断循环,返回到您的原始版本(进行上述更正)- 参见注释 - 或者您可以尝试使用更复杂的查询,该查询只会匹配一次:
Elements elems = doc.select("td.yfnc_tablehead1:containsOwn("+sharesOutstanding+") + td.yfnc_tabledata1");
if ( ! elems.isEmpty() ) {
System.out.println( elems.get(0).owntext() );
}
这个 selector 为您提供所有 td
元素,其 class 是 yfnc_tabledata1
,其紧邻的前一个兄弟是 td
元素,其 class 是 yfnc_tablehead1
并且其自己的文本包含 "Shares Outstanding:" 字符串。这基本上应该 select 您需要的确切 TD。
注意:这个答案的前一个版本是关于 Elements.select()
和 Element.select()
之间的区别的长篇大论。事实证明我完全错了,你的原始版本应该有效——如果你纠正了以上四点。因此,直接设置记录:Elements
上的 select()
实际上会查看每个元素的内部,结果列表可能包含原始列表中与 selection 匹配的任何元素的后代.抱歉。
尝试练习使用 JSoup 从 table 中提取数据。无法弄清楚为什么我不能从
中提取 "Shares Outstanding" 字段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();
}
尝试 return:构建成功,仅此而已。
我在我的浏览器上禁用了 JavaScript 并且 table 仍然显示,所以我假设这不是写在 JavaScript 而是 HTML.
如有任何建议,我们将不胜感激。
编辑后关于您的来源的说明:
- 你应该比较
ownText()
而不是text()
。text()
为您提供所有元素及其所有子元素的组合文本。在本例中,元素包含Shares Outstanding<font size="-1"><sup>5</sup></font>:
,因此其组合文本为"Shares Outstanding5:"
。如果您使用ownText
,它将只是"Shares Outstanding:"
。 - 注意冒号 (
:
)。相应地更新sharesOutstanding
中的值。 - 你传错了URL。
AAPL
. 后面应该有一个 - 您当前的查询(至少是第二次尝试)返回元素两次,因为有一个嵌套 table 所以它找到了两次 TD。
+
您可以在找到匹配项后中断循环,返回到您的原始版本(进行上述更正)- 参见注释 - 或者您可以尝试使用更复杂的查询,该查询只会匹配一次:
Elements elems = doc.select("td.yfnc_tablehead1:containsOwn("+sharesOutstanding+") + td.yfnc_tabledata1");
if ( ! elems.isEmpty() ) {
System.out.println( elems.get(0).owntext() );
}
这个 selector 为您提供所有 td
元素,其 class 是 yfnc_tabledata1
,其紧邻的前一个兄弟是 td
元素,其 class 是 yfnc_tablehead1
并且其自己的文本包含 "Shares Outstanding:" 字符串。这基本上应该 select 您需要的确切 TD。
注意:这个答案的前一个版本是关于 Elements.select()
和 Element.select()
之间的区别的长篇大论。事实证明我完全错了,你的原始版本应该有效——如果你纠正了以上四点。因此,直接设置记录:Elements
上的 select()
实际上会查看每个元素的内部,结果列表可能包含原始列表中与 selection 匹配的任何元素的后代.抱歉。