是否可以让机器人根据网站发送消息?

vol*_*fer 1 python bots discord discord.py

我想做的是,每当网站上有新内容时,我的不和谐机器人就会发送一条消息说“嘿,那里有新内容”。例如,有一个图书网站,他们上传有关图书的新帖子及其描述,而我的机器人只是从该帖子在线获取文本并将其发送到我的不和谐服务器。我希望它足够清楚。这里我有用 Python 3.9 编写的基本不和谐机器人代码

import discord 
from discord.ext import commands

client = commands.Bot(command_prefix = '!')

@client.event 
async def on_ready():
    print("Bot is working.")

client.run('not today')
Run Code Online (Sandbox Code Playgroud)

Jac*_*Lee 6

有关更多详细信息,我建议查看该discord.ext.tasks模块的文档,该模块允许您为机器人运行后台任务。这对于框架的更加个性化的实现尤其方便。

问题的两部分都不太难:

  1. 创建一个网络抓取工具来检查 HTML 页面内的更新
  2. 创建一个利用所述网络抓取工具的后台任务。

创建网络抓取工具

用于网页抓取的包完全符合开发人员的愿望/需求。由于discord.py使用asyncio,您应该使用异步解析器,例如aiohttp, 或 ,requests-html而不是urllibrequests,后者是阻塞的。

使用 AIOHTTP

import aiohttp

RECENT_HTML = ""

async def download_webpage():
    async with aiohttp.ClientSession() as session:
        async with session.get("<url>") as response:
            if response.status != 200:
                # Notify users that the website could not be scraped

            html = await response.text()
            if html != RECENT_HTML:
                # Notify users of changes within the website
                # An HTML parser could be used to identify specific changes within the HTML
                # Or you could just tell the members that a change occurred.
            RECENT_HTML = html
Run Code Online (Sandbox Code Playgroud)

这些download_webpage()协程创建一个会话来下载网页(替换"<url>"为网站的实际 URL,然后通过将页面 HTML 与 进行比较来简单地检查网页是否已更改RECENT_HTMLRECENT_HTML仅存储已抓取的 HTML 的最新版本,以进行比较. 要检查的 HTML 不必存储为变量,例如可以将其写入文件。

如果 HTML 不同,您可以简单地通知成员,也可以使用 HTML 解析器来获取确切的差异。请注意,这些更改可能是微妙且无关紧要的(例如,页面上的广告在检查之间发生了更改),因此我建议检查特定元素内的更改。(但是,这样做超出了本问题的范围。)

最后,页面 HTML 的新副本存储在变量中(或者存储 HTML 的最新版本)。

带请求-HTML

from requests_html import AsyncHTMLSession

RECENT_HTML = ""

async def download_webpage():
    asession = AsyncHTMLSession()
    response = await asession.get("<url>")
    if response.status_code != 200:
        # Notify users that the website could not be scraped
    
    html = response.html.text
    if html != RECENT_HTML:
        # Notify users of changes within the website
        # An HTML parser could be used to identify specific changes within the HTML
        # Or you could just tell the members that a change occurred.
    RECENT_HTML = html
Run Code Online (Sandbox Code Playgroud)

创建后台任务

装饰discord.ext.tasks.loop围绕一个协程,将其调度为按确定的时间间隔运行的后台任务。间隔(作为浮点或整数)可以以秒、分钟、小时或三者的组合为单位。

from discord.ext import tasks

@tasks.loop(seconds=5.0)
async def my_task():
    # Do something that is repeated every 5 seconds
Run Code Online (Sandbox Code Playgroud)

因此,将两者结合起来,您的网络抓取任务可能如下所示:

import aiohttp
from discord.ext import tasks

RECENT_HTML = ""

@tasks.loop(hours=1)
async def download_webpage():
    async with aiohttp.ClientSession() as session:
        async with session.get("<url>") as response:
            if response.status != 200:
                # Notify users that the website could not be scraped

            html = await response.text()
            if html != RECENT_HTML:
                # Notify users of changes within the website
                # An HTML parser could be used to identify specific changes within the HTML
                # Or you could just tell the members that a change occurred.
            RECENT_HTML = html
Run Code Online (Sandbox Code Playgroud)


小智 5

您可以使用tasks.loop以下方式查看新闻:

import bs4
import aiohttp
from discord.ext import tasks

@tasks.loop(minutes=1)
async def check_news():
  async with aiohttp.ClientSession() as ses:
    async with ses.get(your_url) as response:
      if response.status == 200:
        text = await response.text()
        soup = bs4.BeautifulSoup(text, "html.parser")
        #finding the news
        #if there is a new post, you can send it to spesific channel.
Run Code Online (Sandbox Code Playgroud)

如果您可以分享链接,我可以提供进一步帮助。