为何使用Telethon批量发消息时反复出现Flood Wait Error?
问题解决指南
一、Flood Wait Error 问题
你遭遇的Flood Wait错误,核心原因有两点:
- 异步函数里用
time.sleep()会阻塞整个事件循环,导致请求队列混乱,没法精准控制请求频率; - 手动sleep逻辑不完整:
get_input_entity()属于API请求,会被计入每分钟20次的限制,但你只在send_message()后加了sleep,忽略了前者的请求次数。
解决方案:
- 用
asyncio.sleep()替换time.sleep(),异步等待不会阻塞事件循环; - 完全依赖Telethon内置的防洪水机制:Telethon客户端默认会自动捕获
FloodWaitError,并按要求等待后重试,无需手动设置sleep,保持默认配置即可。
二、SessionRevokedError 问题
这个错误大概率是短时间内大量GetHistoryRequest触发了Telegram的安全检测,被判定为异常操作,进而撤销了会话。另外,重复调用get_input_entity()增加了请求频率,也会加剧风险。
解决方案:
- 缓存已获取的实体,避免重复调用
get_input_entity(); - 降低历史记录请求频率,调大
iter_messages()的wait_time参数,或者分批处理用户列表; - 如果会话已被撤销,删除本地会话文件(
for_otzv.session),重新登录授权。
修改后的代码示例
from telethon import TelegramClient import asyncio async def main(client): # 缓存实体,减少重复API请求 entities = {} user_list = ['@user1', '@user2', ..., '@user50'] # 批量发送消息 for username in user_list: if username not in entities: entities[username] = await client.get_input_entity(username) await client.send_message(entity=entities[username], message='message1') # 可选:如需额外控制发送间隔,用异步sleep await asyncio.sleep(2) # 批量获取历史消息 for username in user_list: entity = entities.get(username) or await client.get_input_entity(username) # 调大wait_time,降低请求频率 async for message in client.iter_messages(entity, wait_time=15, limit=60): print(message.text) # 替换为你的业务逻辑 api_id='...' api_hash='...' # 用异步方式初始化客户端,避免sync模块的潜在问题 client = TelegramClient('for_otzv', api_id, api_hash) async def run(): await client.start() await main(client) await client.disconnect() asyncio.run(run())
额外注意事项
- 异步函数里禁止使用任何阻塞式同步操作(比如
time.sleep()、同步IO); - 尽量减少不必要的API请求,比如缓存实体、合并重复操作;
- 如需更严格的频率控制,可使用
asyncio.Semaphore限制并发请求数。
内容的提问来源于stack exchange,提问作者Валентин Мышковский
相关产品推荐
相关产品推荐

