添加DateTime过滤后Pyrogram出现FloodWait错误的原因排查
问题原因排查与解决
核心原因
加了日期过滤后触发FloodWait,本质是API请求次数暴增,超过了Telegram的限流阈值。原来的代码大概率用了Pyrogram内置的批量消息获取逻辑(比如get_history),一次请求能拉多条消息;修改后可能踩了这两个坑:
- 循环里频繁调用
get_replies、get_messages这类单条请求接口,每检查一条消息的日期就发起一次API请求,请求量直接翻倍甚至暴涨; - 没用到Pyrogram自带的服务器端日期过滤参数,反而拉取所有历史消息后本地筛选,导致拉取的消息总量远超之前,间接增加了请求次数。
具体排查方向
- 查修改后的代码是不是在循环里反复调用单条消息接口:比如原来批量拉完消息直接处理,现在改成每条消息单独调API拿时间戳,这必然触发限流;
- 确认是不是丢了
get_history的offset_date/reverse参数:这俩参数能让Telegram服务器直接返回指定日期的消息,不用本地全量拉取后筛选。如果原来用了,改代码时删了,就会拉取大量无关消息,增加请求次数; - 检查批量拉取的
limit参数:比如原来设limit=100一次拉100条,改后改成limit=1,导致要几十上百次请求才能拉完,自然触发限流。
修复方案
- 用Pyrogram内置的服务器端日期过滤(最优解)
直接让Telegram服务器只返回目标日期的消息,减少拉取量和请求次数:from datetime import datetime, timedelta # 定义目标日期范围 start_date = datetime(2023, 8, 27) end_date = datetime(2023, 8, 28) + timedelta(days=1) # 包含28日全天 # 批量拉取指定日期的消息 async for message in app.get_history( chat_id=CHAT_ID, offset_date=end_date, reverse=True ): if message.date >= start_date: # 处理符合条件的消息 with open("results.txt", "a") as f: f.write(f"{message.id}, {message.document.file_name}\n") else: # 因为reverse=True,消息按时间升序排列,早于start_date就可以停止遍历 break - 别在循环里频繁调用单条API
如果要处理回复消息,别每条都调get_replies,尽量批量获取后再处理。 - 临时处理FloodWait异常
Pyrogram支持自动处理短时间的限流,初始化客户端时加个参数就行:
如果等待时间更长,手动捕获异常等待:app = Client( "my_account", api_id=API_ID, api_hash=API_HASH, flood_sleep_threshold=10 # 自动处理等待时间≤10秒的FloodWait )from pyrogram.errors import FloodWait import asyncio try: # 你的API调用代码 except FloodWait as e: print(f"要等{e.value}秒") await asyncio.sleep(e.value)
内容的提问来源于stack exchange,提问作者Peter Long
相关产品推荐
相关产品推荐

