You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Yahoo Stocks API部分退市股票报错,Python异常捕获失效求优化

解决Yfinance API退市股票触发AttributeError且捕获失效的高效优化方案

我一直用Yahoo的yfinance库批量获取全球多交易所股票数据,之前代码运行正常,但API更新后,部分退市股票(比如ANTM)会触发AttributeError: 'float' object has no attribute 'upper'错误,而且原代码的try-except根本抓不到这个异常,直接导致代码卡死无限运行。我搞了个临时解决办法,但处理上千只股票时速度慢得离谱,现在要找个能高效捕获异常、不拖慢运行速度的优化方案。

原代码

!pip install yfinance
import yfinance as yf
import datetime as dt
start = '2021-01-01'
end =  dt.datetime.today().strftime('%Y-%m-%d')
            
tickers=['AAPL', 'ANTM']
            
for ticker in tickers:
    try:
        df=yf.download(ticker, start, end, progress=False)
        df.index = df.index.strftime('%Y/%m/%d')
        df.to_csv(f'{ticker}.csv')
    except Exception: 
        if ticker not in tickers:
            continue

临时解决方案(性能瓶颈)

我加了个前置检查,先通过yf.Ticker(ticker).info['regularMarketPrice']判断股票是否活跃,但这个方法每次都要额外请求一次API,处理上千只股票时重复请求导致速度骤降:

# 临时 workaround 代码
tickers=['AAPL','ANTM']
        
for ticker in tickers:
    try:
        if yf.Ticker(ticker).info['regularMarketPrice'] != None:  # 额外API请求拖慢速度
            df=yf.download(ticker, start, end, progress=False)
            df.index = df.index.strftime('%Y/%m/%d')
            df.to_csv(f'{ticker}.csv')
        else:
            continue
    except Exception: 
        if ticker not in tickers:
            continue

高效优化方案

1. 精准捕获特定异常,清理无效逻辑

原try-except抓不到异常,是因为错误发生在yf.download内部的特定代码路径,直接捕获AttributeError并针对性处理,同时去掉无意义的ticker not in tickers判断(循环里的ticker肯定在列表里):

import yfinance as yf
import datetime as dt

start = '2021-01-01'
end = dt.datetime.today().strftime('%Y/%m/%d')
tickers=['AAPL', 'ANTM']

for ticker in tickers:
    try:
        df = yf.download(ticker, start, end, progress=False)
        # 先检查数据是否有效,避免后续处理空DataFrame报错
        if df.empty:
            print(f"{ticker} 无有效数据(可能已退市)")
            continue
        df.index = df.index.strftime('%Y/%m/%d')
        df.to_csv(f'{ticker}.csv')
    except AttributeError as e:
        if "'float' object has no attribute 'upper'" in str(e):
            print(f"{ticker} 触发退市相关错误,跳过")
            continue
    except Exception as e:
        print(f"{ticker} 出现其他错误: {e}")
        continue

2. 批量请求减少API调用次数

yfinance支持批量下载多个ticker,一次性请求能大幅减少API交互次数,提升效率,同时在批量结果里过滤无效数据:

import yfinance as yf
import datetime as dt

start = '2021-01-01'
end = dt.datetime.today().strftime('%Y/%m/%d')
tickers=['AAPL', 'ANTM']

# 优先批量下载所有ticker数据
try:
    df_batch = yf.download(tickers, start, end, progress=False, group_by='ticker')
    for ticker in tickers:
        # 提取单只股票的数据
        ticker_df = df_batch[ticker]
        if ticker_df.empty:
            print(f"{ticker} 无有效数据(可能已退市)")
            continue
        ticker_df.index = ticker_df.index.strftime('%Y/%m/%d')
        ticker_df.to_csv(f'{ticker}.csv')
except AttributeError as e:
    # 若批量请求中出现退市股票错误,转为逐个处理异常ticker
    print("批量请求触发错误,转为逐个处理")
    for ticker in tickers:
        try:
            df = yf.download(ticker, start, end, progress=False)
            if df.empty:
                print(f"{ticker} 无有效数据")
                continue
            df.index = df.index.strftime('%Y/%m/%d')
            df.to_csv(f'{ticker}.csv')
        except AttributeError as e:
            if "'float' object has no attribute 'upper'" in str(e):
                print(f"{ticker} 已退市,跳过")
                continue

3. 禁用不必要的API字段请求

通过yf.download的参数减少不必要的数据请求,比如关闭分红拆分数据、自动调整等,进一步提升速度:

df = yf.download(ticker, start, end, progress=False, 
                 actions=False, auto_adjust=False, threads=True)

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 23:10:52