调用Hypixel API时异步请求为何与同步请求速度接近?
异步调用Hypixel API速度未提升的问题分析
我编写的代码以异步方式调用Hypixel API,但运行速度并未比同步调用版本更快。当前需发送50-60次请求,耗时约1分钟,请问问题出在哪里?
# 获取总页数 def Page_count(): response = requests.get('https://api.hypixel.net/v2/skyblock/auctions?page=1').json() total_pages = response["totalPages"] return total_pages # 获取单页数据的异步函数 async def get_page(session, url): async with session.get(url) as response: page = await response.json() # 打印获取到的页码 print("Got Page: " + str(page['page'] + 1)) return page['auctions'] # 异步获取所有页面数据 async def main(total_pages): async with aiohttp.ClientSession() as session: # 创建任务列表(所有API调用) tasks = [] for page_number in range(total_pages): url = f"https://api.hypixel.net/v2/skyblock/auctions?page={page_number}" tasks.append(asyncio.ensure_future(get_page(session, url))) # 收集所有响应 print("Requesting Pages!") pages_data = await asyncio.gather(*tasks) print('整理列表') all_auctions = [auction for page in pages_data for auction in page] return all_auctions total_pages = Page_count() # 统计页数 auctions = asyncio.run(main(total_pages)) print('共有 ' + str(len(auctions)) + ' 个拍卖品') # 打印拍卖品总数
问题根源
- 触发API速率限制:你一次性创建了所有50-60个请求任务并同时发起,Hypixel API有严格的请求频率限制,短时间内大量并发请求会被服务器限流,导致请求排队等待,最终耗时和同步调用几乎一致。
- 同步代码残留:
Page_count函数使用了同步的requests.get,虽然只执行一次,但如果这步响应慢也会占用部分时间,破坏了全程异步的优势。
解决方案
1. 限制并发请求数量
用asyncio.Semaphore控制同时发起的请求数,避免触发限流。一般设置为5-10个并发即可,可根据实际情况调整。
2. 全程异步化
把Page_count改成异步函数,使用aiohttp发起请求,消除同步阻塞。
修改后的代码示例
import asyncio import aiohttp # 异步获取总页数 async def Page_count(session): async with session.get('https://api.hypixel.net/v2/skyblock/auctions?page=1') as response: data = await response.json() return data["totalPages"] # 获取单页数据的异步函数(带并发限制) async def get_page(session, url, semaphore): async with semaphore: async with session.get(url) as response: page = await response.json() print("Got Page: " + str(page['page'] + 1)) return page['auctions'] # 异步获取所有页面数据 async def main(): async with aiohttp.ClientSession() as session: total_pages = await Page_count(session) # 设置并发限制为5 semaphore = asyncio.Semaphore(5) tasks = [] for page_number in range(total_pages): url = f"https://api.hypixel.net/v2/skyblock/auctions?page={page_number}" tasks.append(asyncio.create_task(get_page(session, url, semaphore))) print("Requesting Pages!") pages_data = await asyncio.gather(*tasks) print('整理列表') all_auctions = [auction for page in pages_data for auction in page] return all_auctions auctions = asyncio.run(main()) print('共有 ' + str(len(auctions)) + ' 个拍卖品')
说明
Semaphore(5)限制同时最多5个请求在处理,避免触发Hypixel的限流机制,让请求能稳定快速完成。- 把
Page_count改成异步后,全程没有同步阻塞,进一步提升效率。
内容的提问来源于stack exchange,提问作者BlackPhantom
相关产品推荐
相关产品推荐

