Jupyter Notebook调用IEX Cloud API遇JSONDecodeError及代码优化需求
错误原因分析
- 变量名不匹配:你的代码中循环变量是
symbol,但构造API URL时误用了{stock},会导致请求的URL包含无效的股票代码;即便实际运行时循环变量是stock,仍可能存在部分股票代码无效的情况。 - API请求频率限制:IEX Cloud沙箱API有请求速率限制,循环请求全部500只股票时,短时间内的大量请求会触发限制,服务器返回非JSON格式的响应(如HTML错误页),导致
json()解析失败。而请求前5只时请求量小,未触发限制,所以能正常运行。
解决方案
1. 替代append的高效写法
不要每次向DataFrame追加行,而是先创建列表存储所有股票数据,最后一次性转换为DataFrame——这既避免了append被弃用的问题,还能大幅提升性能。
2. 避免请求频率限制
使用IEX Cloud的批量请求API,一次获取多只股票的数据,减少请求次数,规避速率限制。该接口支持用逗号分隔多个股票代码批量请求。
完整修正代码
import pandas as pd import requests from secrets import IEX_CLOUD_API_TOKEN # 读取标普500股票列表 stocks = pd.read_csv('sp_500_stocks.csv') my_columns = ['Ticker', 'Stock Price', 'Market Capitalization', 'Number of Shares to Buy'] # 用列表存储所有股票数据,替代逐行append stock_data_list = [] # 批量请求批次大小(IEX Cloud批量请求上限为100只) batch_size = 100 # 分批次处理所有股票 for start_idx in range(0, len(stocks['Ticker']), batch_size): # 截取当前批次的股票代码,用逗号拼接 batch_tickers = ','.join(stocks['Ticker'][start_idx:start_idx+batch_size]) # 构造批量请求API地址 api_url = f'https://sandbox.iexapis.com/stable/stock/market/batch?symbols={batch_tickers}&types=quote&token={IEX_CLOUD_API_TOKEN}' response = requests.get(api_url) # 先检查响应状态,确保请求成功 if response.status_code != 200: print(f"批次请求失败,状态码:{response.status_code}") continue # 解析响应JSON batch_data = response.json() # 遍历当前批次的每只股票,提取所需数据 for ticker in batch_tickers.split(','): try: quote_info = batch_data[ticker]['quote'] stock_data_list.append({ 'Ticker': ticker, 'Stock Price': quote_info['latestPrice'], 'Market Capitalization': quote_info['marketCap'], 'Number of Shares to Buy': 'N/A' }) except KeyError: print(f"无法获取{ticker}的数据,可能代码无效或API返回异常") # 一次性将列表转换为DataFrame final_dataframe = pd.DataFrame(stock_data_list, columns=my_columns) print(final_dataframe.head())
额外说明
- 批量请求优势:将500只股票分成5次请求,大幅降低请求次数,避免触发IEX Cloud的速率限制。
- 错误容错:添加了状态码检查和KeyError捕获,避免单只股票数据异常导致整个程序崩溃。
- 性能优化:列表收集数据后转DataFrame的方式,比循环
append效率提升数倍,尤其适合处理大量数据。
内容的提问来源于stack exchange,提问作者aimanimran
相关产品推荐
相关产品推荐

