使用Python的Requests和BeautifulSoup无法获取yfinance全部历史数据
问题原因
Yahoo Finance的历史数据页面采用动态加载机制:初始HTTP请求仅返回最近100条交易记录,更早的数据需要通过页面滚动触发AJAX异步请求加载。直接用requests抓取静态HTML只能获取初始渲染的内容,这就是你只能拿到100行数据的核心原因,和BeautifulSoup的解析器无关。
解决方案
方案1:使用yfinance官方库(推荐)
Yahoo提供了官方的Python库yfinance,专门用于获取其金融数据,无需处理动态加载和反爬问题,代码简洁且稳定。
步骤:
- 安装库:
pip install yfinance
- 编写代码获取指定时间段数据:
import yfinance as yf import pandas as pd # 定义股票代码和时间范围 ticker = "HSBC" start_date = "2022-02-17" end_date = "2023-02-16" # 获取数据 hsbc_data = yf.download(ticker, start=start_date, end=end_date) # 查看数据行数和内容 print(f"数据行数:{len(hsbc_data)}") print(hsbc_data.head()) # 保存为CSV(可选) hsbc_data.to_csv("hsbc_history.csv")
该代码会直接返回指定时间段内的所有交易日数据,自动跳过非交易日,最终行数符合你的250行左右的预期。
方案2:模拟动态加载(进阶,不推荐)
如果坚持使用requests和BeautifulSoup,需要找到Yahoo Finance加载历史数据的AJAX接口,模拟滚动时的请求参数(如offset、size等),循环请求拼接数据。但这种方法需要频繁适配接口变化,且容易触发反爬机制,维护成本高。示例思路如下:
- 抓包分析页面滚动时的AJAX请求(通常是下载类接口)
- 构造包含时间范围、间隔等参数的请求,直接获取CSV格式的完整数据(比解析HTML更高效)
- 解析CSV内容为DataFrame
示例代码(接口可能随时变化):
import requests import pandas as pd headers = { "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/110.0" } # 直接请求CSV下载接口,参数对应目标时间范围 url = "https://query1.finance.yahoo.com/v7/finance/download/HSBC?period1=1645075200&period2=1676563200&interval=1d&events=history&includeAdjustedClose=true" response = requests.get(url, headers=headers) # 解析CSV内容 data = pd.read_csv(pd.compat.StringIO(response.text)) print(f"数据行数:{len(data)}") print(data.head())
注意:该接口的参数规则可能会被Yahoo调整,需自行抓包验证最新参数。
内容的提问来源于stack exchange,提问作者Ahithophel Yeboah-Peprah
相关产品推荐
相关产品推荐

