Android Java用Jsoup提取雅虎财经流动负债及日期数据
修复雅虎财经AAPL资产负债表流动负债数据提取代码
问题分析
原代码失效的核心原因是网页中不存在带title=Current Liabilities属性的元素,无法定位流动负债所在行。正确的定位逻辑应该是:
- 通过文本匹配找到“Current Liabilities”对应的表格行
- 从该行提取带
data-test="fin-col"属性的div下的数值 - 从表头提取带
D(ib) Fw(b)类的日期标签,再筛选出2019-2022年9月30日的对应数据
修复后的完整代码
import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class YahooFinanceScraper { // 目标日期范围:2019-2022年9月30日 private static final List<String> TARGET_DATES = List.of("2022-09-30", "2021-09-30", "2020-09-30", "2019-09-30"); public static Map<String, String> extractCurrentLiabilities(String url) throws IOException { Map<String, String> result = new HashMap<>(); List<String> headerDates = new ArrayList<>(); List<String> liabilityValues = new ArrayList<>(); // 1. 获取网页文档(Android中需在子线程执行网络请求) Document doc = Jsoup.connect(url).get(); // 2. 提取表头日期并格式化 Elements dateElements = doc.select("div.D(ib).Fw(b) span"); for (Element dateEl : dateElements) { String dateText = dateEl.text().trim(); String formattedDate = formatYahooDate(dateText); headerDates.add(formattedDate); } // 3. 定位流动负债行 Elements rows = doc.select("div[data-test='fin-row']"); Element currentLiabilitiesRow = null; for (Element row : rows) { Element labelEl = row.selectFirst("div[data-test='fin-label'] span"); if (labelEl != null && labelEl.text().trim().equals("Current Liabilities")) { currentLiabilitiesRow = row; break; } } // 4. 提取流动负债行的数值 if (currentLiabilitiesRow != null) { Elements valueElements = currentLiabilitiesRow.select("div[data-test='fin-col'] span"); for (Element valueEl : valueElements) { liabilityValues.add(valueEl.text().trim()); } } // 5. 匹配目标日期与对应数值 for (int i = 0; i < headerDates.size() && i < liabilityValues.size(); i++) { String date = headerDates.get(i); if (TARGET_DATES.contains(date)) { result.put(date, liabilityValues.get(i)); } } return result; } // 转换雅虎财经日期格式为YYYY-MM-DD private static String formatYahooDate(String rawDate) { String[] parts = rawDate.split(", "); String year = parts[1]; String[] monthDay = parts[0].split(" "); String month = getMonthNumber(monthDay[0]); String day = monthDay[1]; return String.format("%s-%s-%s", year, month, day); } // 月份缩写转两位数字 private static String getMonthNumber(String monthAbbr) { return switch (monthAbbr) { case "Jan" -> "01"; case "Feb" -> "02"; case "Mar" -> "03"; case "Apr" -> "04"; case "May" -> "05"; case "Jun" -> "06"; case "Jul" -> "07"; case "Aug" -> "08"; case "Sep" -> "09"; case "Oct" -> "10"; case "Nov" -> "11"; case "Dec" -> "12"; default -> "00"; }; } // 测试调用(Android中需在子线程执行) public static void main(String[] args) { String url = "https://finance.yahoo.com/quote/AAPL/balance-sheet?p=AAPL"; try { Map<String, String> data = extractCurrentLiabilities(url); System.out.println("流动负债数据(2019-2022年9月30日):"); for (Map.Entry<String, String> entry : data.entrySet()) { System.out.printf("日期:%s,数值:%s%n", entry.getKey(), entry.getValue()); } } catch (IOException e) { e.printStackTrace(); } } }
代码关键说明
- 日期处理:将雅虎财经的
Sep 30, 2022格式转换为标准YYYY-MM-DD格式,方便精准筛选目标日期 - 行定位逻辑:遍历所有表格行,通过
data-test='fin-label'下的文本匹配找到流动负债行,替代原无效的属性定位方式 - 数据匹配:将表头日期与对应行的数值一一绑定,只保留指定年份9月30日的数据
- Android适配:网络请求必须放在子线程执行,需在
AndroidManifest.xml中添加<uses-permission android:name="android.permission.INTERNET"/>权限
内容的提问来源于stack exchange,提问作者Zac1
相关产品推荐
相关产品推荐

