如何使用Python同时从服务器批量获取币安多币种K线数据?
币安多币种K线批量拉取优化方案
核心优化思路
你当前的性能瓶颈来自串行同步请求,以及每次重复拉取全量历史K线的冗余开销,按以下步骤优化后可将总耗时控制在3秒以内:
1. 替换串行请求为异步并发请求
不用逐个发起请求,用异步客户端同时发起109个币种的请求,充分利用网络带宽。
推荐直接用官方python-binance库的异步客户端,示例代码如下:
import asyncio from binance import AsyncClient # 要拉取的交易对列表,提前过滤好109个你需要的币种 symbols = ["ETHUSDT", "BTCUSDT", "BNBUSDT", ...] async def get_klines(client, symbol): try: # 这里如果做增量更新就把limit设为1,首次全量拉取设为500 candles = await client.futures_klines( symbol=symbol, interval=client.KLINE_INTERVAL_5MINUTE, limit=500 ) return symbol, candles except Exception as e: # 异常处理,可自行增加重试逻辑 print(f"{symbol} 拉取失败: {e}") return symbol, None async def main(): client = await AsyncClient.create() # 并发发起所有请求 tasks = [get_klines(client, symbol) for symbol in symbols] results = await asyncio.gather(*tasks) # 处理返回的结果,results里是(交易对, K线数据)的元组 for symbol, candles in results: if candles: # 这里写你自己的业务逻辑 pass await client.close_connection() if __name__ == "__main__": asyncio.run(main())
2. 本地维护K线队列,做增量更新
你不需要每5分钟都拉全量500根K线,只要第一次初始化的时候拉全量存储到本地,后续每次只拉最新的1根已收盘K线追加到本地队列,同时淘汰最老的1根,始终保持本地队列有500根有效数据即可。
这个优化可以把每个请求的返回数据量降低到原来的1/500,单请求耗时可降至几十毫秒,进一步降低总耗时。
3. 额外优化注意事项
- 币安U本位合约K线接口单请求权重为1,109个并发请求总权重仅109,远低于接口每分钟2400的权重限制,不会触发限流
- 可给请求加3次以内的重试逻辑,避免偶发网络波动导致个别币种数据缺失
- 如果并发请求还是有个别超时,可把109个币种拆成2组,每组50多个分批并发,避免瞬间请求量过高
内容的提问来源于stack exchange,提问作者yunusus
相关产品推荐
相关产品推荐

