Discord Bot获取PUBG K/D遇RuntimeWarning协程未等待问题求助
解决Discord机器人中Pubg.get_kd协程未被await的问题
嘿,我一眼就看到你报错的核心原因了——你调用异步函数(协程)的时候没加await!咱们一步步拆解问题,然后给你修复好的代码。
错误根源分析
你看到的RuntimeWarning: coroutine 'Pubg.get_kd' was never awaited,意思是你创建了一个协程对象但从来没让它执行。因为get_kd是用async定义的异步函数,直接self.get_kd()只会返回一个协程对象,不会真正运行里面的逻辑。而且不止这个,你在get_kd里调用self.get_info()的时候也没加await,同样的问题!
另外你的代码还有几个小坑:
- 变量顺序搞反了:
user_info是在调用get_kd之后才定义的,但get_info里要用到user_info[0],这会直接抛出未定义的错误 - 用了同步的
requests库:在Discord.py的异步环境里,同步请求会阻塞整个机器人的事件循环,得换成异步的aiohttp - 没处理除零情况:如果用户没有死亡记录,
deaths_sum是0,计算K/D的时候会炸
修复后的完整代码
import discord from discord.ext import commands import asyncio import aiohttp import json from bs4 import BeautifulSoup as bs class Pubg(): def __init__(self, bot): self.bot = bot # 提前创建aiohttp会话,复用连接更高效 self.session = aiohttp.ClientSession() async def get_info(self, user_name): url = f"https://pubg.op.gg/user/{user_name}" async with self.session.get(url) as resp: url_text = await resp.text() soup = bs(url_text, "lxml") info = soup.find("div", {"class": "player-summary__name"}) playerID = info["data-user_id"] playerNickname = info["data-user_nickname"] season = soup.find("button", {"class": "ranked-stats-wrapper__season-btn"}) currentSeason = season["data-season"] return playerID, playerNickname, currentSeason async def get_kd(self, user_data): # 调用异步函数必须加await playerID, _, currentSeason = await self.get_info(user_data[0]) url = (f"https://pubg.op.gg/api/users/{playerID}/ranked-stats?" f"season={currentSeason}&server={user_data[3]}&queue_size={user_data[1]}&mode={user_data[2]}") async with self.session.get(url) as resp: resp_text = await resp.text() resp_json = json.loads(resp_text) kills = resp_json["stats"]["kills_sum"] deaths = resp_json["stats"]["deaths_sum"] # 处理除零情况 if deaths == 0: KD = "∞" # 没有死亡的话K/D是无穷大 else: killDeath = kills / deaths KD = str(killDeath)[:4] return KD @commands.command(pass_context=True) async def kd(self, ctx): # 先处理用户输入,再调用异步函数 user_info = ctx.message.content.replace(".kd", "").strip() user = user_info.split("-") # 调用get_kd必须加await KD = await self.get_kd(user) await self.bot.say(f"Your K/D is: {KD}") # 机器人关闭时关闭aiohttp会话 def cog_unload(self): asyncio.create_task(self.session.close()) def setup(bot): bot.add_cog(Pubg(bot))
关键修复点说明
- 所有异步函数调用都加了
await:包括get_info和get_kd的调用 - 调整了变量顺序:先解析用户输入,再传递给
get_kd,确保get_info能拿到需要的用户名 - 替换
requests为aiohttp的异步请求,并且复用了ClientSession(更高效) - 增加了除零判断,避免程序崩溃
- 加了
cog_unload方法,在cog卸载时关闭aiohttp会话,避免资源泄漏
内容的提问来源于stack exchange,提问作者Yeah
相关产品推荐
相关产品推荐

