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

关于在if/else循环中使用time.sleep控制API请求速率的技术咨询

解决API限流问题:在嵌套循环中控制请求频率

嘿,针对你遇到的这个API限流问题(每分钟最多6次请求),我来分享几个实用的解决方案,帮你在嵌套循环里优雅地控制请求节奏。

首先,咱们得明确核心需求:在遍历经纬度和年份的两层循环中,确保每分钟发送的请求数不超过6次,避免触发API的限流机制。下面两种方案各有优劣,你可以根据自己的场景选择:

方案1:简单计数式限流(适合请求耗时较短的场景)

这种方式通过计数来控制,每发送6次请求就暂停一分钟,逻辑简单直观,容易实现。

import time

# 假设你的经纬度和年份列表
lats = [31.23, 40.71, 34.05]
lons = [121.47, -74.00, -118.24]
years = [2019, 2020, 2021, 2022, 2023]

request_count = 0
max_requests_per_minute = 6
wait_after_limit = 60  # 达到上限后等待60秒

for lat, lon in zip(lats, lons):
    for year in years:
        # 构造请求参数
        args = {
            'interpolate': False,
            'lat': lat,
            'lon': lon,
            'year': year
            # 补充你的其他参数
        }
        
        # 这里替换成你的API请求代码
        # response = requests.get("你的API地址", params=args)
        print(f"发送请求:纬度{lat},经度{lon},年份{year}")
        
        request_count += 1
        
        # 检查是否达到限流阈值,注意最后一次请求不需要等待
        is_last_request = (lat == lats[-1]) and (year == years[-1])
        if request_count % max_requests_per_minute == 0 and not is_last_request:
            print(f"已发送{request_count}次请求,触发限流,等待60秒...")
            time.sleep(wait_after_limit)

优点:代码简洁,容易理解和维护。
缺点:如果单个请求耗时较长(比如超过10秒),可能会导致一分钟内实际发送的请求数不足6次;反之,如果请求极快,可能会在短时间内发完6次,剩下的时间空闲。

方案2:时间窗口式限流(更精确,适配请求耗时波动的场景)

这种方式会记录每次请求的时间戳,确保在任意60秒的窗口内,请求数不超过6次,能更精准地贴合API的限流规则。

import time
from collections import deque

lats = [31.23, 40.71, 34.05]
lons = [121.47, -74.00, -118.24]
years = [2019, 2020, 2021, 2022, 2023]

max_requests_per_minute = 6
time_window = 60  # 时间窗口为60秒
# 用双端队列存储最近6次请求的时间戳,自动淘汰超出窗口的记录
request_timestamps = deque(maxlen=max_requests_per_minute)

for lat, lon in zip(lats, lons):
    for year in years:
        args = {
            'interpolate': False,
            'lat': lat,
            'lon': lon,
            'year': year
            # 补充你的其他参数
        }
        
        now = time.time()
        
        # 移除时间窗口外的旧请求记录
        while request_timestamps and now - request_timestamps[0] > time_window:
            request_timestamps.popleft()
        
        # 如果窗口内已经有6次请求,计算需要等待的时间
        if len(request_timestamps) >= max_requests_per_minute:
            wait_seconds = time_window - (now - request_timestamps[0])
            print(f"请求达到限流阈值,等待{wait_seconds:.1f}秒...")
            time.sleep(wait_seconds)
            # 等待后更新当前时间
            now = time.time()
        
        # 发送API请求
        # response = requests.get("你的API地址", params=args)
        print(f"发送请求:纬度{lat},经度{lon},年份{year}")
        
        # 记录当前请求的时间戳
        request_timestamps.append(now)

优点:精准控制请求频率,不管单个请求耗时多久,都不会违反每分钟6次的限制。
缺点:代码比计数式稍复杂,但逻辑清晰,稳定性更强。

额外建议:处理API限流错误(429状态码)

即使做了限流控制,有时候还是可能因为网络延迟、API侧的统计误差等原因收到429(请求过多)的响应。这时候可以添加重试机制,配合指数退避策略:

import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry

# 创建带重试策略的会话
session = requests.Session()
# 设置重试规则:最多重试3次,遇到429错误时自动重试,每次等待时间指数增长
retry_strategy = Retry(
    total=3,
    backoff_factor=1,  # 等待时间:1s → 2s → 4s
    status_forcelist=[429],
)
adapter = HTTPAdapter(max_retries=retry_strategy)
session.mount("https://", adapter)
session.mount("http://", adapter)

# 之后用session.get/post发送请求,会自动处理429重试
# response = session.get("你的API地址", params=args)

最后提醒一下,最好再仔细核对一下API的官方文档,确认限流规则是严格的“每分钟6次”,还是滚动窗口限制,或者有没有额外的每日请求上限,这样能让你的限流逻辑更贴合实际要求。

内容的提问来源于stack exchange,提问作者Pyrmon55

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 03:45:46