Discord Bot调用client.get_guild(id).members触发AttributeError求助
解决Discord Bot中Guild对象为None及成员获取的问题
看起来你的代码遇到了两个核心问题:guild对象为None导致无法访问members属性,以及角色判断的逻辑错误。我来一步步帮你解决:
1. 为什么guild是None?
这个错误通常有两个主要原因:
- Bot还没完成初始化/缓存就调用了函数:如果在
client还没成功登录Discord、加载公会缓存之前就调用extractAdmins(),get_guild()自然拿不到数据,返回None。 - 缺少必要的Intents权限:Discord.py v2.0及以上版本需要显式声明要使用的intents,尤其是
membersintent,否则Bot无法获取公会成员数据。
2. 修复步骤
第一步:配置正确的Intents
首先,你需要在Discord开发者门户(Bot页面)开启"Server Members Intent"权限,然后在代码中启用对应的intents:
import discord from discord.ext import commands # 配置intents intents = discord.Intents.default() intents.members = True # 必须开启这个才能获取成员列表 client = discord.Client(intents=intents) # 或者用commands.Bot的话: # bot = commands.Bot(command_prefix='!', intents=intents)
第二步:确保在Bot就绪后执行函数
不要在代码顶部直接调用extractAdmins(),而是放在on_ready事件里,确保Bot已经成功连接并加载了公会缓存:
@client.event async def on_ready(): print(f'Logged in as {client.user}') await extractAdmins() # 这里调用函数,注意要加await,因为下面修改后的函数是异步的
第三步:修正角色判断逻辑
你的代码里直接把role对象和字符串比较是不对的,应该比较role.name(角色名称)或者role.id(角色ID,更可靠,避免名称重复):
async def extractAdmins(): guild = client.get_guild(guild_id_num) if guild is None: print("无法找到目标公会,请检查公会ID是否正确,或者Bot是否在该公会中") return # 打开文件,用with语句更安全,自动关闭文件 with open("counselors.txt", "w", encoding="utf-8") as f: for member in guild.members: # 检查成员是否有目标角色 has_target_role = any(role.name in ["admin", "EstudianteOrientador"] for role in member.roles) if has_target_role: f.write(f"{member.name}\n") # 或者用member.display_name获取显示名称
额外注意事项
- 确保Bot已经被邀请到目标公会,并且拥有"查看成员"的权限,否则无法获取成员列表。
- 用
with语句操作文件比手动open/close更安全,能避免忘记关闭文件或者异常导致文件未关闭的问题。 - 如果角色名称可能有大小写差异,可以把
role.name.lower()和小写的目标字符串比较,比如role.name.lower() in ["admin", "estudianteorientador"]。
内容的提问来源于stack exchange,提问作者Fernando Bermúdez
相关产品推荐
相关产品推荐

