使用discord.py开发加密货币价格查询机器人遇Rate Limit问题
问题解决:Discord.py机器人修改频道名称触发速率限制
问题根源
你遇到的429速率限制错误,核心原因就是Discord的频道名称修改频率限制:每个频道每10分钟最多允许修改2次。你的机器人原本每120秒就尝试修改一次频道名,远超过这个限制阈值,必然触发Rate Limit。
另外代码里还有几个隐性问题:
- 全局变量
loaded逻辑无效,每次进入任务都会被重置为False,导致每次都重新加载页面而非刷新 - 使用
time.sleep(5)会阻塞整个Discord事件循环,影响机器人其他功能运行 - 频道ID处的
asd是未替换的占位符,属于语法错误
解决方案
核心优化:控制频道修改频率
只在价格实际发生变化时才尝试修改频道名,同时添加时间校验,确保10分钟内修改次数不超过2次。
完整修正代码
from selenium import webdriver from selenium.webdriver.common.by import By import asyncio import discord from discord.ext import tasks from discord.ext.commands import Bot import re # 全局配置与状态变量 sentmessage = False last_price = "unknown" last_channel_edit_time = 0 CHANNEL_ID = 1078699389679325316 # 替换为你的目标频道ID ROLE_PING = "<@&asd>" # 替换为需要@的角色ID TOKEN = "asd" # 替换为你的机器人Token intents = discord.Intents.all() client = Bot(command_prefix="!", intents=intents) # Selenium无头浏览器配置 options = webdriver.ChromeOptions() options.add_argument("--headless=new") options.add_argument("--no-sandbox") options.add_argument("--disable-gpu") driver = webdriver.Chrome(options=options) @tasks.loop(seconds=120) async def refreshprice(): global last_price, sentmessage, last_channel_edit_time try: # 首次加载页面,后续仅刷新 if driver.current_url == "data:,": driver.get("你的私有数据链接") else: driver.refresh() await asyncio.sleep(5) # 异步等待页面加载,避免阻塞事件循环 # 提取并格式化价格 buggyprice = driver.find_element(By.XPATH,"/html/body/div/div/div[2]/div/div/div/div[4]/div[2]/div[1]/div[1]/div[1]").text pricewithdollar = buggyprice.partition("\n")[0] current_price = int(re.sub(r"\D+", "", pricewithdollar)) # 仅当价格变化时执行后续操作 if current_price != last_price: last_price = current_price channel = client.get_channel(CHANNEL_ID) # 控制频道修改频率:每5分钟最多修改1次,确保10分钟内不超2次 current_time = asyncio.get_event_loop().time() time_since_last_edit = current_time - last_channel_edit_time if time_since_last_edit > 300 or last_channel_edit_time == 0: await channel.edit(name=f"tfs {current_price}") last_channel_edit_time = current_time # 触发通知逻辑 if not sentmessage: if current_price > 99999: sentmessage = True await channel.send(f"{ROLE_PING} A fairspin kaszinó profitja 100k fölött van! GG a profithoz!") elif current_price < -99999: sentmessage = True await channel.send(f"{ROLE_PING} A fairspin kaszinó profitja -100k alatt van! Most rakd be a tfs-ed!") else: if -99999 < current_price < 99999: sentmessage = False except Exception as e: print(f"获取价格时出错: {e}") @client.tree.command(name="tfsprice", description="Check tfs token price") async def first_command(interaction): await interaction.response.send_message(f"The casino profit is {last_price}$") @client.event async def on_ready(): await client.tree.sync() if not refreshprice.is_running(): refreshprice.start() print("Ready!") client.run(TOKEN)
关键修改说明
- 频率控制:通过记录上次修改频道的时间,确保至少间隔5分钟才修改一次,刚好适配Discord 10分钟2次的限制
- 异步优化:用
asyncio.sleep()替代time.sleep(),避免阻塞机器人事件循环,保证其他功能正常运行 - 触发逻辑优化:仅当价格发生变化时才执行频道修改和通知,减少不必要的API调用
- 错误捕获:添加异常捕获块,避免页面加载失败导致机器人崩溃
内容的提问来源于stack exchange,提问作者mrsalai
相关产品推荐
相关产品推荐

