You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Java用Jsoup提取雅虎财经流动负债及日期数据

修复雅虎财经AAPL资产负债表流动负债数据提取代码

问题分析

原代码失效的核心原因是网页中不存在带title=Current Liabilities属性的元素,无法定位流动负债所在行。正确的定位逻辑应该是:

  1. 通过文本匹配找到“Current Liabilities”对应的表格行
  2. 从该行提取带data-test="fin-col"属性的div下的数值
  3. 从表头提取带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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 19:56:13