如何用requests库控制API调用频次以规避调用限制?
控制API调用频次的实现方案
需求背景
调用目标API存在以下频次限制:
- 每分钟最多60次调用
- 每日最多5000次调用
触发限制时会返回429状态码,需基于requests库实现调用频次控制,在接近限制时自动休眠并继续执行。
现有代码:
import requests for url in list_of_endpoints: url=url headers ={ 'Authorization' : f'Bearer {store_new_access_token[0]}' } response = requests.get(url, headers=headers)
解决方案
通过记录调用时间戳管控每分钟调用量,同时处理429状态码的重试逻辑,具体实现如下:
完整代码
import requests import time from collections import deque # 初始化调用记录容器与限制阈值 call_timestamps = deque() # 存储1分钟内的调用时间戳 daily_call_count = 0 MAX_CALLS_PER_MINUTE = 60 MAX_CALLS_PER_DAY = 5000 for url in list_of_endpoints: # 检查每日调用是否超限 if daily_call_count >= MAX_CALLS_PER_DAY: print("每日调用次数已达上限,等待次日重置") # 计算到次日的等待时间(可根据API实际重置时间调整) wait_time = 86400 - (time.time() % 86400) time.sleep(wait_time) daily_call_count = 0 # 管控每分钟调用频次 current_time = time.time() # 清除1分钟前的调用记录 while call_timestamps and current_time - call_timestamps[0] > 60: call_timestamps.popleft() # 接近分钟上限时自动休眠 if len(call_timestamps) >= MAX_CALLS_PER_MINUTE: sleep_duration = 60 - (current_time - call_timestamps[0]) print(f"接近每分钟调用上限,休眠{sleep_duration:.2f}秒") time.sleep(sleep_duration) # 休眠后重新清理过期记录 current_time = time.time() while call_timestamps and current_time - call_timestamps[0] > 60: call_timestamps.popleft() # 发起API请求 headers = { 'Authorization': f'Bearer {store_new_access_token[0]}' } response = requests.get(url, headers=headers) # 处理429限流状态码 while response.status_code == 429: # 优先使用API返回的Retry-After头确定休眠时间,无则默认60秒 retry_after = int(response.headers.get('Retry-After', 60)) print(f"触发429限制,休眠{retry_after}秒后重试") time.sleep(retry_after) response = requests.get(url, headers=headers) # 更新调用记录 call_timestamps.append(time.time()) daily_call_count += 1 # 此处可添加对响应结果的处理逻辑 # print(response.json())
关键逻辑说明
- 分钟级限流:用双端队列
deque存储最近1分钟的调用时间戳,每次调用前清理过期记录,若当前队列长度接近60,则计算剩余时间并休眠,确保不超过每分钟限制。 - 日级限流:用计数器记录每日调用次数,达到上限后等待次日重置(实际场景可根据API的每日重置时间调整等待逻辑)。
- 429异常处理:收到429状态码时,优先遵循API返回的
Retry-After头指定的休眠时间,无该头则默认休眠60秒后重试,避免持续触发限流。
内容的提问来源于stack exchange,提问作者play_something_good
相关产品推荐
相关产品推荐

