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

Discord机器人触发429限流错误的解决方法及代码优化

解决Discord比特币统计机器人的429限流与状态缺失问题

你的问题核心是调用频率过高触发Discord API限流,同时网页爬取逻辑不合理,导致数据缺失和机器人崩溃。下面是针对性的修改方案:

原代码的关键问题

  • 每3秒爬一次CoinGecko网页:完全没必要,比特币统计数据不会高频更新,还容易被目标网站反爬。
  • 每3秒调用一次change_presence:Discord对状态更新有频率限制,短时间多次调用直接触发429限流,导致机器人无响应。
  • 全局变量Count管理混乱:循环中直接修改全局变量,容易出现索引越界或状态跳变。
  • 任务启动方式错误:on_ready里直接调用命令函数,上下文传递错误,导致逻辑异常。
  • 依赖固定XPath解析网页:CoinGecko页面结构一旦变化,数据就会缺失。

修改后的完整代码

改用CoinGecko官方API(更稳定),分开数据更新和状态切换的循环,缓存数据避免重复请求:

import discord
from discord.ext import commands, tasks
import requests
import asyncio

intents = discord.Intents.default()
intents.message_content = True
intents.members = True
bot = commands.Bot(command_prefix='.', intents=intents)

# 缓存统计数据和状态索引
stats_cache = []
current_stat_index = 0
# CoinGecko官方API端点
COINGECKO_API_URL = "https://api.coingecko.com/api/v3/coins/bitcoin"

def fetch_bitcoin_stats():
    """从CoinGecko API获取比特币统计数据,返回格式化后的列表"""
    try:
        response = requests.get(COINGECKO_API_URL, timeout=10)
        response.raise_for_status()
        data = response.json()
        
        price = f"${data['market_data']['current_price']['usd']:,.2f}"
        h24_change = data['market_data']['price_change_percentage_24h']
        
        stats = [
            f"1h: {data['market_data']['price_change_percentage_1h_in_currency']['usd']:.2f}%",
            f"24h: {h24_change:.2f}%",
            f"7d: {data['market_data']['price_change_percentage_7d_in_currency']['usd']:.2f}%",
            f"30d: {data['market_data']['price_change_percentage_30d_in_currency']['usd']:.2f}%",
            f"1y: {data['market_data']['price_change_percentage_1y_in_currency']['usd']:.2f}%",
            f"24h Low: ${data['market_data']['low_24h']['usd']:,.2f}",
            f"24h High: ${data['market_data']['high_24h']['usd']:,.2f}"
        ]
        
        return price, h24_change, stats
    except Exception as e:
        print(f"获取数据失败: {e}")
        return None, None, []

@tasks.loop(minutes=5)  # 每5分钟更新一次数据,避免频繁请求
async def update_stats_task():
    global stats_cache
    price, h24_change, stats = fetch_bitcoin_stats()
    if price and h24_change is not None and stats:
        stats_cache = stats
        # 更新机器人昵称
        guild = discord.utils.get(bot.guilds, name="тесты")
        if guild:
            member = guild.get_member(1066093484890656951)
            if member:
                nick_suffix = " (↗)" if h24_change >= 0 else " (↘)"
                await member.edit(nick=f"{price}{nick_suffix}")

@tasks.loop(seconds=3)  # 每3秒切换一次状态
async def rotate_presence_task():
    global current_stat_index
    if not stats_cache:
        return  # 缓存为空时不切换状态
    
    # 循环切换状态,避免索引越界
    current_stat = stats_cache[current_stat_index]
    await bot.change_presence(
        activity=discord.Activity(type=discord.ActivityType.watching, name=current_stat)
    )
    
    current_stat_index = (current_stat_index + 1) % len(stats_cache)

@bot.event
async def on_ready():
    print(f"已登录为 {bot.user}")
    # 启动两个独立任务:数据更新和状态切换
    update_stats_task.start()
    rotate_presence_task.start()

if __name__ == "__main__":
    bot.run('MyTokenHere')  # 替换为你的机器人令牌

关键改动说明

  1. 使用CoinGecko官方API:替代网页爬取,数据更稳定,避免XPath失效问题,同时合规性更好。
  2. 分离数据更新和状态切换:
    • update_stats_task每5分钟更新一次数据,大幅减少API请求频率。
    • rotate_presence_task每3秒切换一次状态,使用缓存的数据,避免重复请求。
  3. 安全管理状态索引:用取模运算(current_stat_index + 1) % len(stats_cache)保证索引不会越界,状态循环更稳定。
  4. 正确启动任务:在on_ready中启动tasks.loop任务,符合discord.py规范,避免上下文错误。
  5. 错误处理:添加API请求的异常捕获,避免单个请求失败导致整个机器人崩溃。

额外建议

  • 如果仍遇到Discord限流,可把状态切换间隔从3秒调到5秒,进一步降低调用频率。
  • 可以给CoinGecko API请求添加本地缓存,避免重复请求。
  • 不要频繁修改机器人昵称,当前每5分钟修改一次的频率是安全的。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 23:30:43