You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何确定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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:02:15