
直接解析 google finance 页面 html 获取年化收益率不可靠且易失效;推荐使用专业金融数据包 yfinance,通过官方 api 稳定获取历史价格并计算年化收益,避免反爬、结构变动与法律风险。
直接解析 google finance 页面 html 获取年化收益率不可靠且易失效;推荐使用专业金融数据包 yfinance,通过官方 api 稳定获取历史价格并计算年化收益,避免反爬、结构变动与法律风险。
Google Finance 网页结构频繁更新(如 class="JwB6zf" 等选择器随时可能变更或移除),且其页面依赖 JavaScript 渲染、存在反爬机制(如验证码、IP 限流),导致基于 BeautifulSoup 的静态 HTML 解析极易失败——正如您代码中 performance_tag = soup.find("div", class_="JwB6zf") 返回 None 所示。更关键的是,Google Finance 不公开提供“年化收益率”这一聚合指标的独立 DOM 节点;它通常以图表+文本混合形式动态渲染,无法通过简单 CSS 类精准定位。
✅ 推荐方案:改用 yfinance(Yahoo Finance 官方数据接口封装)
yfinance 是目前 Python 生态中最稳定、维护最活跃的免费金融数据工具,无需登录、无严格配额、支持多周期历史数据下载,并可轻松计算年化收益率:
import yfinance as yf
import pandas as pd
import numpy as np
def get_annual_return(ticker: str, period: str = "1y") -> float:
"""
计算指定股票在 period 周期内的简单年化收益率(基于收盘价)
注意:此处为「持有期年化」,非年化波动率或 CAGR(复利年化),适用于 1 年窗口
"""
stock = yf.Ticker(ticker)
hist = stock.history(period=period)
if len(hist) < 2:
raise ValueError(f"No sufficient price data for {ticker}")
start_price = hist["Close"].iloc[0]
end_price = hist["Close"].iloc[-1]
# 简单年化收益率 = (期末价 / 期初价 - 1) × 年化因子(1Y 即为 1)
annual_return = (end_price / start_price - 1) * 1.0
return round(annual_return, 4)
# 示例:诺和诺德(NVO)在 NYSE 上市,对应 ticker 为 "NVO"
try:
ret = get_annual_return("NVO", period="1y")
print(f"NVO 过去一年年化收益率: {ret:.2%}")
except Exception as e:
print(f"获取失败: {e}")? 注意事项:
- ✅
yfinance返回的是真实、经复权调整的收盘价(Adj Close),建议使用hist["Adj Close"]替代Close以消除分红/拆股影响; - ⚠️ 不要依赖 Google Finance 或 Yahoo Finance 的网页 HTML——它们未授权第三方爬取,且违反其 Terms of Service;
- ? 若需精确的复合年增长率(CAGR),应使用对数收益率或
pandas.DataFrame.pct_change().add(1).prod() ** (252/len(df)) - 1进行日频年化; - ? 备选库:
investpy(支持欧洲/亚洲交易所)、alpha_vantage(需免费 API Key)、pandas-datareader(部分源已弃用),但yfinance对美股、港股、ETF 支持最全面。
总结:放弃脆弱的 HTML 解析,拥抱标准化金融数据接口——一行 pip install yfinance,即可获得可靠、可复现、合规的年化收益计算能力。


















