Python 3.11.9中如何捕获yfinance的‘invalid crumb’异常及KeyError?
解决yfinance捕获404/Invalid Crumb异常及KeyError问题
问题根源
- 404异常捕获无效的原因:创建
yf.Ticker(symbol)时不会立即发起网络请求,只有当访问stock.info属性时才会触发数据拉取,所以你第一个循环里的异常捕获根本不会生效。另外yfinance内部可能将requests的HTTPError包装为自身异常,或者直接返回空字典而非抛出异常。 - Invalid Crumb错误:这是yfinance与Yahoo Finance接口交互时的凭证过期问题,可能需要重试或延迟请求。
修正后的代码
import requests import time import yfinance as yf import pandas as pd # 读取股票代码列表 df = pd.read_excel('company_list_404.xlsx') symbols = df['Symbol'].values.tolist() valid_data = [] for symbol in symbols: try: stock = yf.Ticker(symbol) # 强制触发数据请求,这里才会抛出网络相关异常 info = stock.info # 检查info是否有效(避免Invalid Crumb导致的空数据) if not info: print(f"Symbol {symbol} 返回空数据(可能Invalid Crumb)") continue # 获取forwardPE,处理KeyError forward_pe = info['forwardPE'] valid_data.append({'symbol': symbol, 'forwardPE': forward_pe}) print(f"成功获取 {symbol} 的forwardPE: {forward_pe}") except requests.exceptions.HTTPError as e: print(f"Symbol {symbol} 触发HTTP错误: {e}") continue except KeyError: print(f"Symbol {symbol} 无forwardPE数据") continue except Exception as e: # 捕获其他可能的异常(比如Invalid Crumb对应的内部异常) if "Invalid Crumb" in str(e): print(f"Symbol {symbol} 触发Invalid Crumb错误,重试一次...") # 延迟后重试一次 time.sleep(2) try: info = yf.Ticker(symbol).info forward_pe = info['forwardPE'] valid_data.append({'symbol': symbol, 'forwardPE': forward_pe}) print(f"重试后成功获取 {symbol} 的forwardPE: {forward_pe}") except: print(f"重试后仍失败,跳过 {symbol}") continue else: print(f"Symbol {symbol} 触发未知错误: {e}") continue # 将有效数据保存为DataFrame result_df = pd.DataFrame(valid_data) result_df.to_excel('valid_stock_pe.xlsx', index=False)
关键改进点
- 合并循环:直接在一个循环中完成请求和数据提取,避免无效的预收集步骤
- 延迟重试:针对Invalid Crumb错误添加简单的重试机制,提高成功率
- 异常分层捕获:先捕获明确的HTTPError、KeyError,再用通用Exception处理特殊的Invalid Crumb情况
- 空数据检查:提前判断
info是否为空,避免后续操作报错
内容的提问来源于stack exchange,提问作者Arline
相关产品推荐
相关产品推荐

