discord.py+SQLite3脏话过滤器失效:发送违规词无提示
解决Discord.py脏话过滤器失效的问题
我帮你排查出了几个导致过滤器没反应的关键问题,咱们一步步修正:
1. 查询结果的判断逻辑错误
cursor.fetchall() 无论是否查到数据,返回的都是列表类型——没有匹配数据时返回空列表 [],而不是 None。所以你原来的 if result is None: 永远不会触发,完全可以去掉这个判断,直接处理返回的列表即可。
2. 脏话匹配逻辑搞反了
你写的匹配条件完全颠倒了:
if any(b in bword for b in message.content.lower()):
这段代码的意思是:把消息内容拆成单个字符,检查每个字符是否存在于脏话列表中——这显然不是你想要的脏话检测逻辑!
正确的逻辑应该是遍历脏话列表,检查是否有任意一个脏话出现在消息内容里:
if any(word in message.content.lower() for word in bword):
3. 修复SQL注入风险(重要优化)
直接用f-string拼接SQL语句存在严重的SQL注入风险,应该改用参数化查询来传递guild_id:
cursor.execute("SELECT text FROM badwords WHERE guild_id = ?", (message.guild.id,))
4. 优化数据库连接管理
手动调用cursor.close()和db.close()容易遗漏,建议用with上下文管理器自动处理资源释放,代码更简洁安全。
修正后的完整代码
@commands.Cog.listener() async def on_message(self, message): if message.author.bot: return # 使用上下文管理器处理数据库连接 with sqlite3.connect('main.db') as db: cursor = db.cursor() # 参数化查询避免SQL注入 cursor.execute("SELECT text FROM badwords WHERE guild_id = ?", (message.guild.id,)) result = cursor.fetchall() # 提取脏话列表 bword = [x[0] for x in result] # 正确的脏话匹配逻辑 if any(word in message.content.lower() for word in bword): await message.channel.send("plz no swear my bot is noob")
这样修改后,你的脏话过滤器应该就能正常工作了!如果还是没反应,可以检查一下main.db里的badwords表是否正确存储了对应服务器的违规词汇哦。
内容的提问来源于stack exchange,提问作者Cedric




