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

Android端Java抓取HTML表格EBIT数值及日期的技术求助

解决Yahoo财经EBIT数据抓取问题

问题概述

现有代码使用Jsoup抓取Yahoo财经页面(示例URL:https://finance.yahoo.com/quote/AAPL/financials?p=AAPL&guccounter=2)时,正则匹配完全失效,仅输出“Nothing matched: ”。需要实现以下目标:

  • 抓取年度标签页中EBIT(息税前利润)行的4个年度数值及对应日期
  • 抓取Quarterly标签页中EBIT行的4个季度数值及对应日期
  • 输出为日期与数值对应的集合或哈希表

原代码失效原因

  1. 正则表达式硬编码模板字符串(如$seperatorColor),但Jsoup获取的是前端渲染后的实际页面内容,模板变量已被替换为真实值,导致匹配失败
  2. 盲目遍历所有div标签,未定位到EBIT行的上下文,匹配逻辑毫无针对性

可行抓取方案

核心思路

利用页面中data-test属性定位财务表格的行和列(Yahoo财经的财务模块用该属性做了明确标识,比class更稳定),直接定位EBIT所在行后提取对应数据。年度/季度数据通过URL参数切换,无需模拟页面交互。

代码实现

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.HashMap;
import java.util.Map;

public class YahooFinanceScraper {
    private static final String 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";

    public static Map<String, String> fetchEBITData(String baseUrl) throws IOException {
        Map<String, String> ebitData = new HashMap<>();
        
        // 抓取年度EBIT数据
        Document annualDoc = Jsoup.connect(baseUrl).userAgent(USER_AGENT).get();
        extractEBITRow(annualDoc, ebitData, "年度_");
        
        // 抓取季度EBIT数据,通过URL参数切换标签页
        String quarterlyUrl = baseUrl.replace("/financials", "/financials?period=quarter");
        Document quarterlyDoc = Jsoup.connect(quarterlyUrl).userAgent(USER_AGENT).get();
        extractEBITRow(quarterlyDoc, ebitData, "季度_");
        
        return ebitData;
    }

    private static void extractEBITRow(Document doc, Map<String, String> dataMap, String prefix) {
        // 定位所有财务数据行
        Elements rows = doc.select("div[data-test=fin-row]");
        for (Element row : rows) {
            // 找到EBIT对应的行
            Element labelCol = row.selectFirst("div[data-test=fin-col]:first-child span");
            if (labelCol != null && labelCol.text().trim().equals("EBIT")) {
                // 提取该行的所有数据列(日期+数值)
                Elements dataCols = row.select("div[data-test=fin-col]:not(:first-child)");
                for (Element col : dataCols) {
                    String date = col.attr("title"); // 日期存储在title属性中
                    String value = col.text().trim(); // 数值为列内文本
                    dataMap.put(prefix + date, value);
                }
                break; // 找到EBIT行后直接退出循环,避免无效遍历
            }
        }
    }
}

代码说明

  • 使用data-test属性精准定位财务行(fin-row)和列(fin-col),避免因class变化导致失效
  • 通过URL参数period=quarter直接切换到季度数据页面,无需模拟点击标签
  • 日期存储在列的title属性中,数值直接提取列内文本,无需复杂解析
  • 最终返回的HashMap以年度_日期/季度_日期为键,EBIT数值为值,清晰区分两类数据

注意事项

  • 保持USER_AGENT为现代浏览器标识,避免被反爬机制拦截
  • 若后续页面结构变更,只需检查data-test属性值是否变化,调整选择器即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 08:10:21