使用grequests时如何避免429错误?
解决grequests请求触发429限流的方案
你遇到的429错误是服务器因请求频率过高触发了限流,核心解决思路是控制请求速率或添加重试机制,以下是几种可行方案:
1. 限制并发请求数
grequests的map()方法支持通过size参数控制同时发送的请求数量,避免一次性批量发送请求触发限流:
import grequests sites = [f"https://fantlab.ru/work{i}" for i in range(1, 10)] # 控制每次同时发送3个请求,可根据服务器调整数值 response = (grequests.get(url, timeout=5) for url in sites) resp = grequests.map(response, size=3) print(resp)
2. 添加429错误的重试机制
针对返回429的请求,捕获错误后按服务器指定时间(或默认时间)等待并重发,优先遵循服务器返回的Retry-After头:
import grequests import time def handle_429(response, *args, **kwargs): if response.status_code == 429: # 获取服务器要求的等待时间,无返回则默认等5秒 retry_after = int(response.headers.get('Retry-After', 5)) time.sleep(retry_after) # 重新发送请求并绑定重试钩子 return grequests.get(response.url, timeout=5, hooks={'response': handle_429}) return response sites = [f"https://fantlab.ru/work{i}" for i in range(1, 10)] requests = (grequests.get(url, timeout=5, hooks={'response': handle_429}) for url in sites) resp = grequests.map(requests, size=3) print(resp)
3. 给请求添加随机延迟
通过随机延迟让请求分散发送,降低短时间内请求集中的概率:
import grequests import time import random sites = [f"https://fantlab.ru/work{i}" for i in range(1, 10)] requests = [] for url in sites: # 随机延迟0.5-2秒,可根据情况调整范围 time.sleep(random.uniform(0.5, 2)) requests.append(grequests.get(url, timeout=5)) resp = grequests.map(requests) print(resp)
额外提示
- 优先组合限制并发数+重试机制,既控制速率又能处理突发限流,平衡效率与合规性。
- 若限流仍频繁,可添加模拟浏览器的请求头伪装:
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'} grequests.get(url, headers=headers, timeout=5)
内容的提问来源于stack exchange,提问作者Mop
相关产品推荐
相关产品推荐

