python asyncio中的不和谐机器人

Posted

技术标签:

【中文标题】python asyncio中的不和谐机器人【英文标题】:Discord bot in python asyncio 【发布时间】:2021-08-18 10:50:09 【问题描述】:

我用python写了一个机器人,机器人功能:显示股票价格,设置价格限制,当达到这个限制时,向discord发送消息。在这个阶段,机器人只能监控一个动作。如何使其异步,以便它可以同时监控多只股票,并且当达到限制时,它会发送特定股票与价格已达到标记的消息不一致。

from bs4 import BeautifulSoup
import discord
from discord.ext import commands
from config import settings


bot = commands.Bot(command_prefix = settings['prefix'], help_command=None)

@bot.event
async def on_message(message):
    await bot.process_commands(message)
    channel = message.channel
    co = '0.content'.format(message).split()
    tes=co[0]
    if tes=='price':
        yo=co[1]
        print(yo)
        headers = 
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0'
        

        r = requests.get(
            ('https://finance.yahoo.com/quote/') + yo + ('?p=') + yo + ('.tsrc=fin-srch'),
            headers=headers)
        soup = BeautifulSoup(r.text, 'lxml')
        content = soup.find('div', "class": 'My(6px) Pos(r) smartphone_Mt(6px)').find('span').text
        print(content)
        await channel.send(f'yo - content')
        return content

    elif tes=='limit':
        p=co[1]
        su=co[2]
        price=float(su)

        while True:
            headers = 
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0'
            
            r = requests.get(
                ('https://finance.yahoo.com/quote/') + p + ('?p=') + p + ('.tsrc=fin-srch'),
                headers=headers)
            soup = BeautifulSoup(r.text, 'lxml')

            content = soup.find('div', "class": 'My(6px) Pos(r) smartphone_Mt(6px)').find('span').text
            con=float(content)
            if price<=con:
                await channel.send("достиг")
                break
            print(content)

        return content

bot.run(settings['token'])

【问题讨论】:

【参考方案1】:

如何使它们异步

要使它们异步,请使用库 aiohttp 而不是 requests,遗憾的是,beautifulsoup 没有其他选择,但我们可以使用 run_in_executor 来实现这一点

你必须做出的改变:

在文件顶部添加import aiohttp(安装 discord.py 时会自动安装 aiohttp) 在定义机器人后添加bot.session = aiohttp.ClientSession()(在bot = commands.Bot... 行之后) 改变
r = requests.get(
            ('https://finance.yahoo.com/quote/') + yo + ('?p=') + yo + ('.tsrc=fin-srch'),
            headers=headers)

async with bot.session.get(
                f'https://finance.yahoo.com/quote/yo?p=yo.tsrc=fin-srch',
                headers=headers
            ) as r:
    # we will also change `r.text` to `await r.text()`

这基本上是使用会话对象,获取网站的原始 html。与请求相同的工作,但 异步

现在
soup = BeautifulSoup(r.text, 'lxml')
content = soup.find('div', "class": 'My(6px) Pos(r) smartphone_Mt(6px)').find('span').text

要使其异步,首先将其添加到函数中

def scrape(html):
    soup = BeautifulSoup(html, 'lxml')
    content = soup.find('div', "class": 'My(6px) Pos(r) smartphone_Mt(6px)').find('span').text
    return content

这只是将 beautifulsoup 代码包装在一个函数中,该函数采用原始 html amd 返回所需的内容。没有其他的 现在在你的on_message,而不是

content = soup.find('div', "class": 'My(6px) Pos(r) smartphone_Mt(6px)').find('span').text

content = await bot.loop.run_in_executor(None, scrape, await r.text())

这会在 scrape 函数中运行代码并将 await r.text() 传递给它,这是原始 html。然后在函数中,我们获取原始 html,找到我们的数据并返回它。这里我们获取返回值,并将其保存到一个名为 content 的变量中

【讨论】:

您是否有任何不理解的特定部分或您觉得难以理解的部分? 我编辑了答案以使其更易于理解:)

以上是关于python asyncio中的不和谐机器人的主要内容,如果未能解决你的问题,请参考以下文章

python中的不和谐机器人

如何阻止不和谐机器人响应自身/所有其他机器人 [Python 3.6 中的不和谐机器人]

我的基于 python 的不和谐机器人没有响应输入的任何命令,并且初始方法没有打印任何内容

如何使用 youtubedl 的搜索功能而不是 url 让我的不和谐机器人播放音乐? (Python)

我将如何使用 python 在我的不和谐机器人上添加冷却时间

如何防止不和谐机器人python中的SQL注入攻击