Python爬取Yahoo Finance财报数据:API调用实践指南


Python爬取Yahoo Finance财报数据:API调用实践指南

本教程详细介绍了如何通过直接调用yahoo finance的内部api来高效、准确地抓取特定日期的公司财报数据。针对传统html解析在动态加载页面上失效的问题,文章提供了基于`requests`库的api请求方法,包括请求头、参数、json查询体的构建,以及如何处理动态cookie和crumb值,确保稳定获取财报信息。

1. 理解传统爬取方法的局限性

在使用Python进行网页数据抓取时,requests库结合BeautifulSoup是常见的组合。然而,对于许多现代网站,尤其是那些大量依赖J*aScript动态加载内容的网站,这种方法会遇到瓶颈。

以Yahoo Finance的财报日历页面为例,如果尝试直接请求其URL(例如https://finance.yahoo.com/calendar/earnings?day=YYYY-MM-DD)并使用BeautifulSoup解析返回的HTML,可能会发现无法获取到预期的财报数据,或者获取到的数据并非指定日期的最新信息。这通常是因为页面上的财报列表是通过J*aScript在浏览器端异步请求后端API后渲染的,而requests库只获取了初始的静态HTML内容,并未执行J*aScript。

例如,以下尝试获取“昨天”财报的初始代码片段,可能会因为上述原因而失败,导致获取到非预期日期(如周末)的数据:

import requests
from bs4 import BeautifulSoup as bs
from datetime import date, timedelta

today = date.today()
# 假设我们想获取上一个交易日的财报
# 如果今天是周日,timedelta(days=2) 会得到周五
# 但这种简单计算不总是可靠,特别是在处理周末和节假日时
yesterday_attempt = today - timedelta(days=2)

url = f"https://finance.yahoo.com/calendar/earnings?day={yesterday_attempt}"
page = requests.get(url)
soup = bs(page.text, 'html.parser')

# 尝试从soup中查找财报符号,可能会得到错误日期的数据
# print(soup.find('a', 'Fw(600) C($linkColor)').text)

这种方法的失败表明,我们需要一种更深入的方式来与网站交互。

2. 发现并利用Yahoo Finance的内部API

当传统的HTML解析方法失效时,通常意味着网站通过API进行数据交换。我们可以通过浏览器的开发者工具(通常按F12打开)来监控网络请求,从而发现这些隐藏的API。

在Yahoo Finance的财报日历页面,通过观察网络请求,可以发现它向一个特定的API端点发送POST请求来获取财报数据:https://query2.finance.yahoo.com/v1/finance/visualization。这个API返回的数据是JSON格式,结构清晰,非常适合程序化抓取。

Beautiful.ai Beautiful.ai

AI在线创建幻灯片

Beautiful.ai 108 查看详情 Beautiful.ai

3. 构建API请求获取财报数据

要成功调用这个API,我们需要模拟浏览器发送的POST请求,包括正确的请求头、查询参数和JSON请求体。

3.1 确定目标日期

首先,我们需要一个健壮的方法来确定要查询的日期,例如“上一个交易日”。

from datetime import date, timedelta

def get_last_trading_day(current_date: date) -> date:
    """
    获取给定日期之前的最近一个交易日。
    如果给定日期是周末,则回溯到上一个周五。
    """
    target_date = current_date
    # 0=Monday, 1=Tuesday, ..., 4=Friday, 5=Saturday, 6=Sunday
    while target_date.weekday() >= 5: # 如果是周六或周日
        target_date -= timedelta(days=1)
    return target_date

# 示例:获取今天的上一个交易日
today = date.today()
last_trading_day = get_last_trading_day(today)

# API查询需要一个日期范围,通常是目标日期当天
start_date_str = last_trading_day.strftime("%Y-%m-%d")
end_date_str = (last_trading_day + timedelta(days=1)).strftime("%Y-%m-%d") # 范围是 [start_date, end_date)

3.2 构造请求参数和数据

API请求主要由以下几部分组成:

  • 请求头(Headers): 模拟浏览器行为,User-Agent是必需的。
  • URL参数(Params): 包含一些元数据,如crumb、lang、region等。其中crumb是一个动态值,通常用于防止CSRF攻击,需要从Yahoo Finance的其他页面(如主页或任何股票详情页)的HTML中提取,或者通过观察API请求获取。
  • JSON请求体(Query Payload): 这是核心部分,定义了我们想要查询的数据类型、字段、日期范围、分页和排序方式。
import requests
from datetime import date, timedelta

# 1. 确定目标日期
today = date.today()
last_trading_day = get_last_trading_day(today) # 使用上面定义的函数

start_date_str = last_trading_day.strftime("%Y-%m-%d")
end_date_str = (last_trading_day + timedelta(days=1)).strftime("%Y-%m-%d")

# 2. 定义请求头
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
    "Accept": "application/json, text/j*ascript, */*; q=0.01",
    "Content-Type": "application/json",
    "X-Requested-With": "XMLHttpRequest",
    "Referer": "https://finance.yahoo.com/calendar/earnings",
}

# 3. 定义URL和URL参数
url = "https://query2.finance.yahoo.com/v1/finance/visualization"
params = {
    "crumb": "YOUR_CRUMB_VALUE_HERE", # 此值通常是动态的,需要从浏览器开发者工具中获取
    "lang": "en-US",
    "region": "US",
    "corsDomain": "finance.yahoo.com",
}

# 4. 定义JSON请求体 (query payload)
query_payload = {
    "entityIdType": "earnings",
    "includeFields": [
        "ticker",
        "companyshortname",
        "eventname",
        "startdatetime",
        "startdatetimetype",
        "epsestimate",
        "epsactual",
        "epssurprisepct",
        "timeZoneShortName",
        "gmtOffsetMilliSeconds",
    ],
    "offset": 0,
    "query": {
        "operands": [
            {"operands": ["startdatetime", start_date_str], "operator": "gte"}, # 大于等于开始日期
            {"operands": ["startdatetime", end_date_str], "operator": "lt"},    # 小于结束日期
            {"operands": ["region", "us"], "operator": "eq"},
        ],
        "operator": "and",
    },
    "size": 100, # 每页获取条目数
    "sortField": "companyshortname",
    "sortType": "ASC",
}

# 5. 定义Cookie
# 'A3' cookie 通常也包含会话信息,是动态且必需的。
# 同样需要从浏览器开发者工具中获取。
cookie_a3 = "YOUR_A3_COOKIE_VALUE_HERE" # 示例: "d=AQABBK8KXmQCEA8-VE0dBLqG5QEpQ7OglmEFEgABCAHCeWWpZfNtb2UB9qMAAAcIqgpeZJj7vK8&S=AQAAAqhyTAOrxcxONc4ktfzCOkg"

# 6. 发送POST请求并处理响应
with requests.Session() as s:
    s.headers.update(headers)
    s.cookies["A3"] = cookie_a3 # 设置A3 cookie

    try:
        response = s.post(url, params=params, json=query_payload)
        response.raise_for_status() # 如果HTTP请求失败(非200状态码),则抛出异常
        data = response.json()

        # 解析并打印结果
        if data and "finance" in data and "result" in data["finance"] and \
           data["finance"]["result"] and "documents" in data["finance"]["result"][0] and \
           data["finance"]["result"][0]["documents"] and "rows" in data["finance"]["result"][0]["documents"][0]:

            print(f"--- 抓取 {last_trading_day.strftime('%Y年%m月%d日')} 的财报数据 ---")
            for r in data["finance"]["result"][0]["documents"][0]["rows"]:
                company_name = r[1] if len(r) > 1 else "N/A"
                event_name = r[2] if len(r) > 2 and r[2] else "N/A"
                start_time = r[3] if len(r) > 3 else "N/A"
                print(f"{company_name:<40} {event_name:<40} {start_time:<30}")
        else:
            print("未能获取到财报数据,请检查API响应结构或查询参数。")

    except requests.exceptions.RequestException as e:
        print(f"请求失败: {e}")
    except ValueError:
        print("响应内容不是有效的JSON格式。")
    except Exception as e:
        print(f"发生未知错误: {e}")

3.3 示例输出(部分)

运行上述代码,如果crumb和A3 cookie正确,将输出类似以下格式的财报数据:

--- 抓取 2025年12月15日 的财报数据 ---
Lewis and Clark Bank                      Q3 2025  Earnings Release                2025-12-15T13:10:00.000Z      
Alzamend Neuro, Inc.                                                              2025-12-15T16:32:00.000Z      
ATIF Holdings Ltd                         Q1 2025  Earnings Release                2025-12-15T21:00:00.000Z      
Barnwell Industries Inc                   Q4 2025  Earnings Release                2025-12-15T23:05:13.000Z      
Quanex Building Products Corp             Q4 20

以上就是Python爬取Yahoo Finance财报数据:API调用实践指南的详细内容,更多请关注其它相关文章!


# 遍历  # 信阳ai关键词排名技术技巧  # 北仑区网站外贸推广  # 大石桥高端网站建设  # 宿州网站推广选哪家  # 家居市场营销推广方法  # 期货seo推广  # 山东网站优化开发  # 企业网站建设原创  # 电商营销推广资料  # 酒店网站建设硬件配置  # 加载  # 这是  # 是一个  # 周日  # 周末  # javascript  # 迭代  # 交易日  # 迷思  # 财报  # 工  # app  # 浏览器  # cookie  # windows  # json  # js  # html  # java  # python 


相关栏目: 【 Google疑问12 】 【 Facebook疑问10 】 【 优化推广96088 】 【 技术知识133117 】 【 IDC资讯59369 】 【 网络运营7196 】 【 IT资讯61894 】


相关推荐: Python中安全地将环境变量转换为整数的类型注解指南  深入理解J*aScript异步操作:setTimeout与调用栈的真相  《下一站江湖2》风神腿获取攻略  智学网app怎么登录忘记密码_智学网app忘记密码找回与重新登录操作方法  易车网官网直达入口 易车网在线登录入口  mysql镜像配置如何恢复数据_mysql镜像配置数据恢复详细流程  驱动人生:游戏修复指南  OpenWeatherMap API:通过城市名称获取天气预报数据指南  Golang如何操作指针参数_Go pointer参数传递规则  J*aScript桌面应用_Electron多进程架构实战  三星M34录音变声问题_Samsung M34麦克风调整  招商淘客入门指南  MySQL多重JOIN技巧:高效关联同一表获取多角色信息  《kimi智能助手》制作ppt教程  如何在CSS中使用absolute实现登录弹窗居中_transform translate结合  Golang如何使用crypto/md5生成哈希_Golang MD5哈希生成方法  mysql怎么查询数据_mysql基础查询语句使用教程  雨课堂官网在线登录 网页版雨课堂登录链接  苹果iPhone14ProMax如何新建AppleID_iPhone14ProMax新建AppleID具体流程  泰拉瑞亚网页版在线登录入口 泰拉瑞亚官方正版入口  Python自动化抓取GBGB赛狗比赛结果:日期范围与赛道筛选教程  《虎扑》取消评分记录方法  网易云音乐闹钟铃声设置教程  word文档行距怎么调?word文档调行距的操作步骤  掌握CSS :has() 选择器:父选择器、嵌套限制与常见陷阱解析  键盘测试软件哪个好_键盘故障检测工具推荐  重返未来:1999卡戎全方位攻略  Safari浏览器自动填表功能失效怎么办 Safari表单管理修复  京东快递包裹信息查询入口 京东快递官方查询平台入口  PHP与SQL实践:高效实现数据复制与特定列值修改  微博网页版入口链接 微博网页版在线互动平台  PHP动态导航按钮:根据用户登录状态切换链接与文本  J*aScript模块加载器_RequireJS原理分析  如何查询国外邮政编码_国外邮政编码查询的多种有效途径  优化Flask模板中SQLAlchemy查询迭代标签:处理字符串空格问题  邦丰播放器频道搜索设置  使用逻辑应用(Logic Apps)自动处理邮件附件中的XML到Excel  原子笔记app误删找回教程  msn官方入口2025登录 msn官网2025直达首页入口  微信客户端怎么查看二维码_微信客户端个人二维码查看方法  圆通快递官方入口不需要登录 在线查询入口快速查询  快手缓存清理方法  如何使用CSS Grid实现“大方块左侧,小方块右侧垂直堆叠”的水平布局  火狐浏览器如何刷新修复浏览器 火狐浏览器“重置Firefox”功能详解  QQ网页版官方账号登录入口 QQ网页版网页版入口快速导航  抖音如何进行蓝V认证 抖音企业号申请所需资料与流程  mysql离线安装后如何启动_mysql离线安装完成后启动服务的方法  基于 Flink 和 Kafka 实现高效流处理:连续查询与时间窗口  C++ priority_queue怎么用_C++优先队列底层实现与自定义比较器  如何用mysql实现客户反馈管理_mysql客户反馈数据库方法 

 2025-11-09

了解您产品搜索量及市场趋势,制定营销计划

同行竞争及网站分析保障您的广告效果

点击免费数据支持

提交您的需求,1小时内享受我们的专业解答。

运城市盐湖区信雨科技有限公司


运城市盐湖区信雨科技有限公司

运城市盐湖区信雨科技有限公司是一家深耕海外推广领域十年的专业服务商,作为谷歌推广与Facebook广告全球合作伙伴,聚焦外贸企业出海痛点,以数字化营销为核心,提供一站式海外营销解决方案。公司凭借十年行业沉淀与平台官方资源加持,打破传统外贸获客壁垒,助力企业高效开拓全球市场,成为中小企业出海的可靠合作伙伴。

 8156699

 13765294890

 8156699@qq.com

Notice

We and selected third parties use cookies or similar technologies for technical purposes and, with your consent, for other purposes as specified in the cookie policy.
You can consent to the use of such technologies by closing this notice, by interacting with any link or button outside of this notice or by continuing to browse otherwise.