创建Spotify数据集:如何优化循环提升API调用效率?
优化Spotify API数据获取速度的方案
核心问题分析
你的代码运行缓慢的核心原因是串行同步调用API:每个分类的请求必须等待前一个请求完成才能发起,网络IO等待占了绝大多数耗时。另外,频繁使用np.concatenate拼接数组也会带来额外的内存与性能开销(每次拼接都会创建新数组)。
具体优化方法
1. 改用异步并行请求API
将串行的API调用改为异步并行,同时发起多个请求,大幅压缩总等待时间。使用aiohttp实现异步请求时,注意遵守Spotify API的请求速率限制(通常为每分钟180次),通过信号量控制并发数,避免触发限流。
示例代码(假设原get_category_playlists为同步请求,改为异步版本):
import aiohttp import asyncio import numpy as np async def async_get_category_playlists(session, category_id, auth_token): url = f"https://api.spotify.com/v1/browse/categories/{category_id}/playlists?limit=50&offset=0" async with session.get(url, headers={"Authorization": f"Bearer {auth_token}"}) as resp: return await resp.json() async def main(category_ids, auth_token): playlists = { "ids": [], "messages": [] } # 控制并发数,避免触发API限流 semaphore = asyncio.Semaphore(10) async def fetch_category(category_id): async with semaphore: async with aiohttp.ClientSession() as session: playlists_data = await async_get_category_playlists(session, category_id, auth_token) items = playlists_data['playlists']['items'] message = playlists_data.get('message', '') # 先用普通列表收集数据,最后统一转numpy playlists["ids"].extend([item['id'] for item in items]) playlists["messages"].extend([message] * len(items)) tasks = [fetch_category(cid) for cid in category_ids] await asyncio.gather(*tasks) # 一次性转换为numpy数组,避免频繁拼接的开销 playlists["ids"] = np.array(playlists["ids"]) return playlists # 执行异步逻辑 category_ids_list = categories_df['ids'].tolist() your_auth_token = "YOUR_SPOTIFY_ACCESS_TOKEN" playlists = asyncio.run(main(category_ids_list, your_auth_token))
2. 优化数组拼接逻辑
原代码每次循环都调用np.concatenate,会反复创建新数组,效率低下。改为先将所有ID存入普通Python列表,最后一次性转换为numpy数组,能显著减少内存操作开销。
3. 缓存重复请求
如果脚本需要多次运行,可以将已获取的分类数据缓存到本地(比如用pickle存储为文件),避免重复请求相同的API接口。
4. 确认API参数上限
当前使用的limit=50已经是Spotify API允许的最大值,无需调整;若后续需要获取更多数据,可通过offset分页,但需注意分页请求的并发控制。
内容的提问来源于stack exchange,提问作者guilherme guerra
相关产品推荐
相关产品推荐

