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

Discord转Twitter Python机器人报429请求过多错误求解决

Discord机器人触发429 Too Many Requests错误的原因及修复方案

错误原因

从错误栈可以明确,错误发生在Discord机器人的登录阶段,触发了Discord API的429限流机制,核心原因包括:

  • 短时间内频繁重启机器人,导致登录请求超出Discord的API速率限制
  • 代码中存在重复的API调用(如每次on_message事件都调用client.get_channel获取频道,额外增加请求量)
  • 同步请求阻塞事件循环:使用requests同步下载图片,会导致Discord客户端无法及时处理心跳和其他API请求,间接引发限流

修复方案

1. 解决登录阶段限流

  • 避免短时间内重复启动机器人,测试环境下每次重启间隔至少1-2分钟
  • 显式启用自动重连机制:client.run("my_token", reconnect=True),让机器人在限流解除后自动重试登录

2. 减少不必要的API请求

  • 缓存目标频道对象:在on_ready事件中提前获取并缓存频道,无需每次on_message重复调用API:
    target_channel = None
    
    @client.event
    async def on_ready():
        global target_channel
        target_channel = client.get_channel(973613949935317023)
        print(f"已登录,监控频道:{target_channel.name}")
    
    # 在on_message中直接使用缓存的频道对象判断
    if message.channel == target_channel:
        # 后续处理逻辑
    

3. 替换同步请求为异步请求

使用aiohttp替代requests下载图片,避免阻塞Discord的事件循环:

import aiohttp
import io

# 在on_message的图片处理部分替换为:
async with aiohttp.ClientSession() as session:
    async with session.get(image_url) as resp:
        img_data = await resp.read()
        img = Image.open(io.BytesIO(img_data))

4. 优化图片处理逻辑

不要循环复用同一个文件名,改用临时文件避免覆盖或占用问题,同时修复原代码中字符串格式化的错误:

import tempfile

# 循环处理附件时:
for attachment in attachments:
    image_url = attachment.url
    # 下载图片(使用上面的异步逻辑)
    # 用临时文件保存
    with tempfile.NamedTemporaryFile(suffix='.png', delete=False) as tmp_file:
        img.save(tmp_file)
        tmp_filename = tmp_file.name
    
    media = api.media_upload(tmp_filename)
    client2.create_tweet(
        text=f'😈 {message.author} JUST made this at @leveragedevils! Join while you still can! We would love to have you! 😈                     #btc #eth #solnfts #crypto #stocks #money #levdevtrading #sol #nft',
        media_ids=[media.media_id])
    # 上传后删除临时文件
    os.unlink(tmp_filename)

5. 添加限流异常处理

在关键逻辑处捕获429错误,根据Discord返回的Retry-After头延迟重试:

import asyncio

@client.event
async def on_error(event, *args, **kwargs):
    error = kwargs.get('error')
    if isinstance(error, discord.HTTPException) and error.status == 429:
        retry_after = int(error.response.headers.get('Retry-After', 5))
        print(f"触发限流,{retry_after}秒后重试")
        await asyncio.sleep(retry_after)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 09:50:41