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

Android Java中如何匹配Div标签提取EBIT等财务数据?

Yahoo财经财报数据提取问题解决方案

问题梳理

  • 从AAPL财报页提取EBIT的年度(9/30/2022-2019)和季度(9/30/2022、6/30/2022、3/31/2022、12/31/2021)数据,输出键值对或集合
  • 提取对应Div标签的日期值
  • 解决资产负债表折叠行数据提取及季度数据AJAX动态加载问题

原代码核心问题

  1. 误用正则匹配HTML:正则不适用于解析HTML结构,Jsoup自带的CSS选择器是更可靠的方案
  2. 正则语法错误:正则中未定义捕获组,group(1)会抛出异常;^$强制匹配div完整HTML,实际页面元素存在空格/隐藏节点导致匹配失败
  3. 遍历效率低下:遍历所有div标签完全没必要,直接定位目标元素即可

修正后的代码方案

1. 年度EBIT数据提取(静态页面)

利用Jsoup的CSS选择器直接定位目标元素,无需正则:

private static void fetchAnnualEBIT(String url) throws IOException {
    String userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36";
    Document doc = Jsoup.connect(url).userAgent(userAgent).get();

    // 提取年度日期表头
    Elements dateSpans = doc.select("div[data-test=\"fin-col\"] span");
    List<String> dates = new ArrayList<>();
    for (Element span : dateSpans) {
        dates.add(span.text().trim());
    }
    Log.d("Annual Dates", dates.toString());

    // 提取EBIT行数据
    Element ebitRow = doc.selectFirst("div:containsOwn(EBIT)");
    if (ebitRow != null) {
        Elements dataSpans = ebitRow.select("div[data-test=\"fin-col\"] span");
        List<String> ebitData = new ArrayList<>();
        for (Element span : dataSpans) {
            ebitData.add(span.text().trim());
        }
        // 组装键值对
        Map<String, String> ebitMap = new HashMap<>();
        for (int i = 0; i < Math.min(dates.size(), ebitData.size()); i++) {
            ebitMap.put(dates.get(i), ebitData.get(i));
        }
        Log.d("Annual EBIT Data", ebitMap.toString());
    } else {
        Log.d("EBIT Row", "Not found");
    }
}

2. 季度数据处理(AJAX动态加载)

Yahoo的季度数据通过AJAX请求加载,需直接调用其数据接口,示例用OkHttp实现:

private static void fetchQuarterlyEBIT(String symbol) throws IOException {
    OkHttpClient client = new OkHttpClient();
    String url = "https://query1.finance.yahoo.com/v10/finance/quoteSummary/" + symbol + "?modules=incomeStatementHistoryQuarterly";
    Request request = new Request.Builder()
            .url(url)
            .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36")
            .build();

    try (Response response = client.newCall(request).execute()) {
        if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
        String json = response.body().string();
        // 解析JSON提取EBIT季度数据,这里可使用Gson/Jackson等库
        Log.d("Quarterly EBIT JSON", json);
    }
}

注:需添加OkHttp依赖,解析JSON时可根据返回结构提取对应日期和EBIT值

3. 资产负债表折叠行数据提取

流动负债的折叠行可通过选择器定位父行后,提取其下属的折叠内容:

private static void fetchCurrentLiabilities(String url) throws IOException {
    String userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36";
    Document doc = Jsoup.connect(url).userAgent(userAgent).get();

    // 定位流动负债父行
    Element currentLiabilitiesRow = doc.selectFirst("div:containsOwn(Current Liabilities)");
    if (currentLiabilitiesRow != null) {
        // 提取折叠的子项数据(需注意页面结构,可能是相邻的div或子元素)
        Elements childRows = currentLiabilitiesRow.nextElementSiblings().select("div[data-test=\"fin-row\"]");
        for (Element row : childRows) {
            String itemName = row.selectFirst("div[data-test=\"fin-col\"] span").text().trim();
            Elements values = row.select("div[data-test=\"fin-col\"] span");
            Log.d("Current Liabilities Item", itemName + ": " + values.get(1).text().trim());
        }
    }
}

关键注意事项

  • User-Agent设置:必须使用现代浏览器的UA,否则Yahoo会拦截请求
  • API接口稳定性:Yahoo的非公开API可能随时变更,需定期验证接口地址
  • JSON解析依赖:处理动态数据时,建议引入Gson或Jackson简化JSON解析

内容的提问来源于stack exchange,提问作者Zac1

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 17:20:34