Python中IEX Cloud API请求过慢问题求代码优化
问题:优化IEX Cloud多证券收盘价API请求的速度与效率
我正尝试从IEX Cloud服务器发起简单API请求,获取多只证券的收盘价。目前已成功拉取数据,但耗时极长且数据量并不大,恳请各位帮忙重构代码以提升速度与效率。以下是我的现有代码:
for i, row in Universe.iterrows(): try: request = urllib.request.urlopen('https://cloud.iexapis.com/stable/stock/'+Universe['ticker'][i]+'/chart/date/'+Px_1+'?chartByDay=true&token=TOKEN').read() data = json.loads(request) Universe['Px_1'][i] = data[0]['close'] except: Universe['Px_1'][i] = np.nan
解决方案:两种高效优化方案
你的代码慢的核心原因是逐个同步请求API——每次请求都要等待服务器响应才能进行下一个,大量时间浪费在网络等待上。下面给你两种针对性的优化方案,能大幅提升效率:
方案1:利用IEX Cloud的批量查询接口(推荐)
IEX Cloud本身支持批量请求多只股票的数据,不用循环单独调用,这是最直接的优化方式,能把N次请求变成1次请求,效率提升非常明显。
代码示例:
import urllib.request import json import pandas as pd import numpy as np # 把所有ticker用逗号拼接成字符串 tickers = ','.join(Universe['ticker'].tolist()) # 构造批量查询的URL url = f'https://cloud.iexapis.com/stable/stock/market/batch?symbols={tickers}&types=chart&chartByDay=true&chartDate={Px_1}&token=TOKEN' try: response = urllib.request.urlopen(url).read() data = json.loads(response) # 遍历每个ticker提取收盘价 for ticker in Universe['ticker']: if ticker in data and data[ticker]['chart']: Universe.loc[Universe['ticker'] == ticker, 'Px_1'] = data[ticker]['chart'][0]['close'] else: Universe.loc[Universe['ticker'] == ticker, 'Px_1'] = np.nan except Exception as e: print(f"请求出错: {e}") Universe['Px_1'] = np.nan
为什么这个方案更好?
- 减少网络请求次数:从N次变成1次,彻底消除多次请求的网络等待开销
- 符合IEX Cloud的API设计,避免触发请求频率限制的风险
方案2:异步请求(适合无法批量查询的场景)
如果后续有其他需要单独请求的场景,用异步请求可以同时发起多个请求,不用逐个等待响应。可以用aiohttp库实现:
代码示例:
import aiohttp import asyncio import pandas as pd import numpy as np async def fetch_close(session, ticker, px_date, token): url = f'https://cloud.iexapis.com/stable/stock/{ticker}/chart/date/{px_date}?chartByDay=true&token={token}' try: async with session.get(url) as response: data = await response.json() return ticker, data[0]['close'] if data else np.nan except Exception as e: print(f"获取{ticker}数据出错: {e}") return ticker, np.nan async def main(): token = 'TOKEN' tasks = [] async with aiohttp.ClientSession() as session: # 给每个ticker创建异步任务 for ticker in Universe['ticker']: task = asyncio.create_task(fetch_close(session, ticker, Px_1, token)) tasks.append(task) # 等待所有任务完成 results = await asyncio.gather(*tasks) # 将结果更新到DataFrame for ticker, close_price in results: Universe.loc[Universe['ticker'] == ticker, 'Px_1'] = close_price # 运行异步主函数 asyncio.run(main())
注意事项:
- 需要先安装
aiohttp:pip install aiohttp - 注意IEX Cloud的请求频率限制,不要一次性发起过多请求(可以设置并发数控制)
内容的提问来源于stack exchange,提问作者Patriots_25
相关产品推荐
相关产品推荐

