如何确定API请求速率限制?批量请求超限额报错求助
解决Riot Games API速率限制问题:如何确认限制规则 + 批量请求优化
一、如何确定Riot API的速率限制
Riot的API速率限制分应用级和用户级两类,你可以通过两种方式明确具体规则:
从响应头获取实时状态
每次请求成功后,接口返回的响应头里会带几个关键字段,直接告诉你当前的速率配额情况:X-Rate-Limit-Type:区分是应用级(app)还是用户级(user)限制,批量用API Key发起请求时,你主要会碰到应用级限制X-Rate-Limit-Limit:返回当前时间段的总请求限额,比如20,100就对应「每秒20次、每2分钟100次」的限制(召唤师查询接口的默认规则)X-Rate-Limit-Remaining:当前时间段内剩余的可用请求数X-Rate-Limit-Reset:当前时间段重置的时间戳(秒级)
你可以在代码里加一行打印这些信息,直观验证:
print("当前限额:", response.headers.get('X-Rate-Limit-Limit'), "剩余请求数:", response.headers.get('X-Rate-Limit-Remaining'))官方接口文档定义
每个Riot API接口都有明确的速率限制说明,你用到的召唤师名称查询接口(summoners/by-name)默认规则是:- 应用级:每秒20次请求,每2分钟100次请求
- 用户级:每秒10次请求,每2分钟50次请求(针对单个用户发起的请求,批量场景基本不用考虑)
二、你的代码优化:处理速率限制
你的当前代码没有任何速率控制逻辑,直接循环1000条数据发起请求,必然触发429错误。这里给你两种实用的优化方案:
方案1:简单固定延迟(适合小批量数据)
直接在每次请求后加一个小延迟,确保每秒请求数不超过20(比如每次延迟0.06秒,每秒约16次,留足缓冲空间):
import requests import pandas as pd import time # 不要用list做变量名,会覆盖Python内置函数 account_ids = [] def requestSummonerData(summonerName, APIKey): URL = f"https://euw1.api.riotgames.com/lol/summoner/v3/summoners/by-name/{summonerName}?api_key={APIKey}" response = requests.get(URL) # 处理速率限制错误 if response.status_code == 429: # 从响应头获取需要等待的时间,Riot会返回Retry-After字段 retry_after = int(response.headers.get('Retry-After', 10)) print(f"触发速率限制,等待{retry_after}秒后重试") time.sleep(retry_after) # 重试请求 return requestSummonerData(summonerName, APIKey) elif response.status_code != 200: print(f"请求失败,状态码:{response.status_code},内容:{response.text}") return None return response.json() def main(): APIKey = input('Copy and paste your API Key here: ') df = pd.read_csv("Data_1000.csv") for index, row in df.iterrows(): summonerName = row['Player_Name'] responseJSON = requestSummonerData(summonerName, APIKey) if responseJSON and 'accountId' in responseJSON: account_id = int(responseJSON['accountId']) account_ids.append(account_id) else: # 请求失败时填充空值,避免数据错位 account_ids.append(None) # 固定延迟控制请求频率 time.sleep(0.06) # 把结果赋值给DataFrame并保存 df["accountId"] = account_ids df.to_csv("Data_with_accountIds.csv", index=False) if __name__ == "__main__": main()
方案2:动态速率控制(适合大批量数据,更高效)
这种方式会根据响应头返回的X-Rate-Limit-Remaining和X-Rate-Limit-Reset动态调整请求间隔,比固定延迟更高效:
import requests import pandas as pd import time from datetime import datetime account_ids = [] def requestSummonerData(summonerName, APIKey, rate_limit_info=None): URL = f"https://euw1.api.riotgames.com/lol/summoner/v3/summoners/by-name/{summonerName}?api_key={APIKey}" # 根据剩余请求数判断是否需要等待 if rate_limit_info: remaining, reset_time = rate_limit_info if remaining <= 2: # 剩余请求数少于2时,等待到重置时间 wait_time = reset_time - datetime.now().timestamp() if wait_time > 0: print(f"剩余请求不足,等待{wait_time:.2f}秒") time.sleep(wait_time) response = requests.get(URL) if response.status_code == 429: retry_after = int(response.headers.get('Retry-After', 10)) print(f"触发速率限制,等待{retry_after}秒后重试") time.sleep(retry_after) return requestSummonerData(summonerName, APIKey) elif response.status_code != 200: print(f"请求失败,状态码:{response.status_code},内容:{response.text}") return None, None # 更新速率限制信息(取每秒级的限制规则) remaining = int(response.headers.get('X-Rate-Limit-Remaining', '20')) reset_time = int(response.headers.get('X-Rate-Limit-Reset', datetime.now().timestamp() + 1)) rate_limit_info = (remaining, reset_time) return response.json(), rate_limit_info def main(): APIKey = input('Copy and paste your API Key here: ') df = pd.read_csv("Data_1000.csv") rate_limit_info = None for index, row in df.iterrows(): summonerName = row['Player_Name'] responseJSON, rate_limit_info = requestSummonerData(summonerName, APIKey, rate_limit_info) if responseJSON and 'accountId' in responseJSON: account_id = int(responseJSON['accountId']) account_ids.append(account_id) else: account_ids.append(None) df["accountId"] = account_ids df.to_csv("Data_with_accountIds.csv", index=False) if __name__ == "__main__": main()
额外注意事项
- 避免用
list作为变量名,这是Python内置类型,会导致潜在的语法问题 - 一定要处理非200的响应状态码,比如404(召唤师名称不存在)、401(API Key无效)等情况
- 如果你的API Key是开发版,限制可能比正式版更低,以响应头返回的信息为准
内容的提问来源于stack exchange,提问作者Sadiksk
相关产品推荐
相关产品推荐

