Discord.py遍历服务器成员时出现随机运行时错误求助
解决Discord机器人遍历成员时的随机错误
Hey there, let's dig into that random error you're hitting with your Discord bot when using get_all_members(). I've dealt with similar quirks before, so here's what's likely going wrong and how to fix it:
可能的问题根源
get_all_members()已被弃用且不稳定:在Discord.py v1.0+版本中,这个生成器已经被标记为过时。它依赖全局成员缓存,而缓存加载不完整、异步迭代时的并发冲突,都很容易引发随机报错。- 异步操作冲突:你在遍历生成器的同时调用
await client.send_message(),这种并发操作可能打乱生成器的迭代状态,导致不可预测的错误。 - 属性过时或未处理空值:
member.game在新版本Discord.py中已经被member.activity取代,如果你的版本较新,直接访问game可能会出问题;另外,如果成员当前没有在玩游戏,member.activity会是None,虽然你转成了字符串,但某些边缘情况仍可能触发异常。
修复方案
1. 启用成员意图并改用guild.members
Discord现在要求机器人启用成员意图才能获取服务器成员列表。先配置好意图:
import discord import asyncio intents = discord.Intents.default() intents.members = True # 启用成员意图 client = discord.Client(intents=intents)
然后放弃全局的get_all_members(),改用当前服务器的guild.members——这是一个缓存好的列表,比生成器稳定得多。
2. 优化异步操作逻辑
先收集所有成员信息,再批量发送消息,避免遍历和发送操作的并发冲突:
@client.event async def on_message(message): # 假设用!listmembers命令触发成员列表查询 if message.content.strip().lower() == '!listmembers': # 确保命令在服务器内使用 if not message.guild: await message.channel.send("This command only works in servers!") return # 先收集所有成员信息,避免遍历中发送消息的并发问题 member_details = [] for member in message.guild.members: username = member.name # 处理无活动的情况,避免空值异常 activity = str(member.activity) if member.activity else "nothing" user_id = member.id member_details.append(f"User {username} (<@{user_id}>) is playing {activity}") # 分条发送消息,加一点延迟避免被Discord限流 for detail in member_details: await message.channel.send(detail) await asyncio.sleep(0.5) # 0.5秒延迟,可根据服务器规模调整 @client.event async def on_ready(): print(f"Logged in as {client.user}") await client.wait_until_ready() # 等待缓存完全加载 print("Bot is ready to go!")
3. 额外的健壮性建议
- 确保你的机器人在服务器中有查看成员的权限,否则
guild.members会返回空列表或不完整的列表。 - 如果服务器成员数量很大,考虑将成员信息合并成几条消息发送,避免发送太多消息触发Discord的限流机制(单频道每分钟最多发送5条消息)。
内容的提问来源于stack exchange,提问作者Neuheit
相关产品推荐
相关产品推荐

