Discord.py技术问题:无需async def实现机器人发送title和name消息
解决方案
可以不用将checkPlayers改成async def,核心思路是利用Discord机器人的事件循环,把异步的消息发送操作调度到循环中执行,具体实现如下:
修改后的代码
def checkPlayers(title, url, keyword, channel, bot): query = keyword.lower() doc = getDoc(url) rows = doc.select('tbody > tr > td > a') for row in rows: name = row.text.lower() if query in name: # 借助机器人的事件循环,异步发送消息 bot.loop.create_task(channel.send(f"{title} {name}")) print(title, name)
关键说明
- 参数补充:给函数新增
channel(要发送消息的频道对象)和bot(Discord机器人实例)两个参数,这样才能调用消息发送接口和访问事件循环。 - 异步调度:
bot.loop.create_task()会把channel.send()这个异步协程加入到机器人的事件队列中执行,不用修改原函数的同步逻辑,原有的HTML解析、匹配逻辑可以完全保留。
注意事项
如果你的getDoc是同步阻塞的IO操作(比如用requests请求网页、BeautifulSoup解析),当这个操作耗时较长时,会阻塞机器人的事件循环,导致机器人无法响应其他指令。这种情况下,可以把IO操作放到线程池里执行,避免阻塞:
def checkPlayers(title, url, keyword, channel, bot): query = keyword.lower() # 把同步IO操作放到线程池执行,不阻塞事件循环 doc = bot.loop.run_in_executor(None, getDoc, url) rows = doc.select('tbody > tr > td > a') for row in rows: name = row.text.lower() if query in name: bot.loop.create_task(channel.send(f"{title} {name}")) print(title, name)
内容的提问来源于stack exchange,提问作者JUN
相关产品推荐
相关产品推荐

