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个季度数值及对应日期
- 输出为日期与数值对应的集合或哈希表
原代码失效原因
- 正则表达式硬编码模板字符串(如
$seperatorColor),但Jsoup获取的是前端渲染后的实际页面内容,模板变量已被替换为真实值,导致匹配失败 - 盲目遍历所有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
相关产品推荐
相关产品推荐

