有关更多详细信息,我建议查看discord.ext.tasks module 的文档,它允许您为机器人运行后台任务。这对于更个性化的框架实现特别方便。
两部分题都不太难:
- 创建一个网络抓取工具,检查页面 HTML 中的更新
- 创建一个使用上述网络爬虫的后台任务。
创建网络抓取工具
用于网页抓取的包完全取决于开发人员的愿望/需求。由于discord.py 使用asyncio,因此您应该使用异步解析器,例如aiohttp 或requests-html,而不是urllib 或requests,它们是阻塞的。
使用 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
这些 download_webpage() 协程创建一个会话来下载网页(将 "<url>" 替换为网站的实际 URL,然后通过将页面 HTML 与 RECENT_HTML 进行比较来检查网页是否更改。RECENT_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
创建后台任务
discord.ext.tasks.loop decorator 包裹了一个协程,将其调度为以确定的时间间隔运行的后台任务。间隔(作为浮点数或整数)可以是秒、分钟、小时或三者的组合。
from discord.ext import tasks
@tasks.loop(seconds=5.0)
async def my_task():
# Do something that is repeated every 5 seconds
因此,将两者结合起来,您的网络爬虫任务可能如下所示:
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