目录
背景
思路
实现
背景
我们可能有时需要关注某个网站的通知更新,以便进行后续操作。比如,时常查看官网的报名通知。但如果手动去看,比较麻烦也容易忘记,所以如果有程序自动监控就比较方便。
思路
定时使用Python爬取网站消息列表,对比是否有新消息发出,如果有的话,就邮件通知自己。
实现
比如这个报名网站,先看他的结构。
我们准备使用xpath来抓取他:
为了方便存储和查询,我们把title转为hash值,用到的python自带的hash()函数
综上,对应的代码就是:
代码语言:javascript复制import requests
from lxml import etree
def get_notification():
store_map = {}
url = r'https://yz.scut.edu.cn/bszs/list.htm'
try:
html = requests.get(url).content.decode('utf-8')
except:
return None
node = etree.HTML(html)
for i in node.xpath('/html/body/section/div[2]/div/div[2]/div[3]/div/div/div/div[1]/ul//li/div'):
title = i.xpath('a[2]/text()')[0]
href = i.xpath('a[2]/@href')[0]
href = href if href.startswith('https') else 'https://yz.scut.edu.cn/' href
date = i.xpath('span[1]/text()')[0]
title_hash = hash(title)
store_map[title_hash] = {'title': title, 'href': href, 'date': date}
return store_map
然后要对比前后两次抓取的内容是否一样,这里使用numpy的差集setdiff1d()函数来实现。
代码示例如下:
代码语言:javascript复制saved_store = get_notification()
saved_lists = np.array(list(saved_store.keys()))
new_store = get_notification()
new_lists = np.array(list(new_store.keys()))
diff = np.setdiff1d(saved_lists, new_lists)
如果差集结果不为空,那就是有新通知了,那就要发邮件提醒。
综上,对应的代码就是:
代码语言:javascript复制import time
import numpy as np
def start():
saved_store = get_notification()
if saved_store is None:
print('启动失败!')
return
saved_lists = np.array(list(saved_store.keys()))
while True:
print('监听中...')
new_store = get_notification()
if new_store is None:
print('获取失败,将重试!')
time.sleep(5)
continue
new_lists = np.array(list(new_store.keys()))
diff = np.setdiff1d(saved_lists, new_lists)
if diff.size != 0:
print('有新通知!')
new_noti = []
for i in diff:
new_noti.append(new_store[i])
print(new_noti)
youxiang('研招有新通知发出', str(new_noti), '1061700625@qq.com')
saved_store = new_store
saved_lists = np.array(list(saved_store.keys()))
time.sleep(60*10)
最后,还有个发邮箱的代码需要补充:
代码语言:javascript复制import smtplib
from email.mime.text import MIMEText
def youxiang(title, msg, receive):
msg_from = 'xxxxxxx@qq.com' # 发送方邮箱
passwd = 'xxxxxx' # 填入发送方邮箱的授权码
receiver = [receive] # 收件人邮箱
subject = title # 主题
content = msg # 正文
msg = MIMEText(content)
msg['Subject'] = subject
msg['From'] = msg_from
msg['To'] = ";".join(receiver) # 收件人为多个收件人,通过join将列表转换为以;为间隔的字符串
s = smtplib.SMTP_SSL("smtp.qq.com", 465) # 邮件服务器及端口号
try:
s.login(msg_from, passwd)
s.sendmail(msg_from, receiver, msg.as_string())
print("邮件已发送成功!")
except Exception as e:
print(e)
finally:
s.quit()
最后,放到服务器上或者一些免费的云函数平台上跑就行了。
以上实现较为粗糙,仅供交流~