You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何修改Python代码获取雅虎财经资产负债表的详细展开数据?

解决雅虎财经资产负债表展开数据爬取问题

我来帮你搞定这个问题——雅虎财经的资产负债表默认只显示汇总数据,那些明细行是折叠状态的,你现在的代码只能抓取页面初始加载的静态内容,而展开后的明细是通过动态加载(AJAX)生成的,所以自然拿不到。下面给你两种实用的解决方案:

方法一:用Selenium模拟点击展开(适合不想研究API的场景)

Selenium可以模拟浏览器的真实操作,点击"Expand All"按钮后等待动态内容加载完成,再抓取完整的表格数据。

步骤&代码示例

  1. 先安装依赖包:
pip install selenium numpy

同时要下载对应浏览器的驱动(比如ChromeDriver),确保驱动路径能被Python识别到。

  1. 修改后的完整爬取代码:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import numpy as np

# 初始化Chrome浏览器(可替换为Firefox等)
driver = webdriver.Chrome()
# 替换为目标股票的资产负债表页面,比如苹果(AAPL)
url = "https://finance.yahoo.com/quote/AAPL/balance-sheet?p=AAPL"
driver.get(url)

try:
    # 等待"Expand All"按钮加载完成并点击
    expand_btn = WebDriverWait(driver, 10).until(
        EC.element_to_be_clickable((By.XPATH, "//button[contains(text(), 'Expand All')]"))
    )
    expand_btn.click()
    # 等待明细数据加载(也可以用更精准的元素等待条件)
    driver.implicitly_wait(5)

    # 对接你原来的解析逻辑
    table_rows = driver.find_elements(By.XPATH, "//div[@data-test='fin-row']")
    parsed_rows = []
    for table_row in table_rows:
        parsed_row = []
        el = table_row.find_elements(By.XPATH, "./div")
        none_count = 0
        for rs in el:
            try:
                text = rs.find_element(By.XPATH, ".//span").text
                parsed_row.append(text)
            except:
                parsed_row.append(np.NaN)
                none_count += 1
        if none_count < 4:
            parsed_rows.append(parsed_row)

finally:
    # 关闭浏览器
    driver.quit()

# 查看结果
for row in parsed_rows:
    print(row)

方法二:直接调用雅虎财经API(更高效,推荐)

雅虎财经网页的财务数据其实是通过官方API获取的,直接请求API可以绕过动态渲染的问题,速度更快也更稳定。

代码示例

import requests
import numpy as np

# 替换为目标股票代码
ticker = "AAPL"
# API地址:modules参数可选balanceSheetHistory(年度数据)或balanceSheetHistoryQuarterly(季度数据)
url = f"https://query1.finance.yahoo.com/v10/finance/quoteSummary/{ticker}?modules=balanceSheetHistory"

# 添加请求头避免被拦截
headers = {
    "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"
}

response = requests.get(url, headers=headers)
data = response.json()

# 解析资产负债表结构化数据
balance_sheet = data["quoteSummary"]["result"][0]["balanceSheetHistory"]["balanceSheetStatements"]
parsed_rows = []

for statement in balance_sheet:
    row = []
    # 按需提取字段,比如现金、应收账款、存货等
    row.append(statement.get("cash", {}).get("raw", np.NaN))
    row.append(statement.get("netReceivables", {}).get("raw", np.NaN))
    row.append(statement.get("inventory", {}).get("raw", np.NaN))
    row.append(statement.get("totalCurrentAssets", {}).get("raw", np.NaN))
    parsed_rows.append(row)

# 打印解析结果
for row in parsed_rows:
    print(row)

说明

  • API返回的是JSON格式的结构化数据,你可以根据需求自由提取任意字段,比解析HTML灵活得多。
  • 一定要添加User-Agent请求头,否则很容易被网站拦截。

原代码问题分析

你原来的代码只解析了页面初始HTML中的表格行,但雅虎财经的明细行默认是隐藏的,只有点击"Expand All"后才会通过AJAX加载到页面DOM中,所以初始HTML里根本没有这些行,自然抓取不到。

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

火山引擎 最新活动