简介

之前在一些地方看到过有些同学等待考研复试分数线、拟录取名单的焦虑,对着学校的官网猛刷新,说手都刷疼了。然后我就在想能不能做一个自动化程序,循环向学校的官网发送请求,然后看看有没有新增通知,如果有的话就发邮件提醒。

适逢我的一个学长二战等待拟录取名单,所以我就帮他写了这个程序(我今年没有进复试所以用不到,希望明年能用到qaq):

首先

首先得有一个网易的邮箱用来发送邮件,然后做如下设置,将这个IMAP/SMTP服务打开,然后会弹出来一个授权码,直接把它复制下来保存好,因为只会弹一次。

程序思路

首先就是很常规的发送请求,然后解析网站,以华科土木水利学院为例,如果有新的通知,会放在这个通知列表的最上方,所以我们直接使用xpath来提取即可,提取后和当前最新的进行比较,如果不一样,说明有新通知,程序停止,并且发邮件提醒

xpath可以直接F12,然后复制:

然后就是常规的get请求与xpath解析:

import requests
from lxml import etree
url = 'http://civil.hust.edu.cn/index/tzgg.htm'
resp = requests.get(url)
resp.encoding='utf-8'
html = etree.HTML(resp.text)
news = html.xpath('//*[@id="line_u8_0"]/div/a/text()')[0]
print(news)

这样就可以把通知的标题打印出来

然后下面是发送邮件模块,有几个地方改一改就可以了

def send():
    # SMTP服务器,这里使用163邮箱
    mail_host = "smtp.163.com"
    # 发件人邮箱, 改成你自己的
    mail_sender = "xxxx@163.com"
    # 邮箱授权码,注意这里不是邮箱密码,如何获取邮箱授权码,看我前面的内容
    mail_license = "xxxxxxxxxxx"
    # 收件人邮箱,可以为多个收件人,写你需要的
    mail_receivers = ["xxxx@qq.com", "xxxx@qq.com", "xxxx@gmail.com"]

    # 构建MIMEMultipart对象代表邮件本身,可以往里面添加文本、图片、附件等
    mm = MIMEMultipart('related')

    # 邮件的主题,可以改成你想发送的
    subject_content = """Python邮件消息"""
    # 设置发送者,注意严格遵守格式,里面邮箱为发件人邮箱,例如:
    mm["From"] = "mach4101<mach4102@163.com>"
    # 设置接受者,注意严格遵守格式,里面邮箱为接受者邮箱
    mm["To"] = "receiver_1_name<xxxx0@qq.com>,receiver_2_name<xxxx@qq.com>, receiver_1_name<xxxx@gmail.com>"
    # 设置邮件主题
    mm["Subject"] = Header(subject_content, 'utf-8')

    # 邮件正文内容
    body_content = """有一条新的消息,快去看看是不是录取通知!!"""
    # 构造文本,参数1:正文内容,参数2:文本格式,参数3:编码方式
    message_text = MIMEText(body_content, "plain", "utf-8")
    # 向MIMEMultipart对象中添加文本对象
    mm.attach(message_text)

    # 创建SMTP对象
    stp = smtplib.SMTP()
    # 设置发件人邮箱的域名和端口,端口地址为25
    stp.connect(mail_host, 25)
    # set_debuglevel(1)可以打印出和SMTP服务器交互的所有信息
    stp.set_debuglevel(1)
    # 登录邮箱,传递参数1:邮箱地址,参数2:邮箱授权码
    stp.login(mail_sender, mail_license)
    # 发送邮件,传递参数1:发件人邮箱地址,参数2:收件人邮箱地址,参数3:把邮件内容格式改为str
    stp.sendmail(mail_sender, mail_receivers, mm.as_string())
    print("邮件发送成功")
    # 关闭SMTP对象
    stp.quit()

最终的程序:

import requests
from lxml import etree
url = 'http://civil.hust.edu.cn/index/tzgg.htm'
import time
import datetime
import smtplib
import email
# 负责构造文本
from email.mime.text import MIMEText
# 负责构造图片
from email.mime.image import MIMEImage
# 负责将多个对象集合起来
from email.mime.multipart import MIMEMultipart
from email.header import Header

def send():
    # SMTP服务器,这里使用163邮箱
    mail_host = "smtp.163.com"
    # 发件人邮箱, 改成你自己的
    mail_sender = "xxxx@163.com"
    # 邮箱授权码,注意这里不是邮箱密码,如何获取邮箱授权码,看我前面的内容
    mail_license = "xxxxxxxxxxx"
    # 收件人邮箱,可以为多个收件人,写你需要的
    mail_receivers = ["xxxx@qq.com", "xxxx@qq.com", "xxxx@gmail.com"]

    # 构建MIMEMultipart对象代表邮件本身,可以往里面添加文本、图片、附件等
    mm = MIMEMultipart('related')

    # 邮件的主题,可以改成你想发送的
    subject_content = """Python邮件消息"""
    # 设置发送者,注意严格遵守格式,里面邮箱为发件人邮箱,例如:
    mm["From"] = "mach4101<mach4102@163.com>"
    # 设置接受者,注意严格遵守格式,里面邮箱为接受者邮箱
    mm["To"] = "receiver_1_name<xxxx0@qq.com>,receiver_2_name<xxxx@qq.com>, receiver_1_name<xxxx@gmail.com>"
    # 设置邮件主题
    mm["Subject"] = Header(subject_content, 'utf-8')

    # 邮件正文内容
    body_content = """有一条新的消息,快去看看是不是录取通知!!"""
    # 构造文本,参数1:正文内容,参数2:文本格式,参数3:编码方式
    message_text = MIMEText(body_content, "plain", "utf-8")
    # 向MIMEMultipart对象中添加文本对象
    mm.attach(message_text)

    # 创建SMTP对象
    stp = smtplib.SMTP()
    # 设置发件人邮箱的域名和端口,端口地址为25
    stp.connect(mail_host, 25)
    # set_debuglevel(1)可以打印出和SMTP服务器交互的所有信息
    stp.set_debuglevel(1)
    # 登录邮箱,传递参数1:邮箱地址,参数2:邮箱授权码
    stp.login(mail_sender, mail_license)
    # 发送邮件,传递参数1:发件人邮箱地址,参数2:收件人邮箱地址,参数3:把邮件内容格式改为str
    stp.sendmail(mail_sender, mail_receivers, mm.as_string())
    print("邮件发送成功")
    # 关闭SMTP对象
    stp.quit()

resp = requests.get(url)
resp.encoding='utf-8'
html = etree.HTML(resp.text)
news = html.xpath('//*[@id="line_u8_0"]/div/a/text()')[0]
while True:
    if news != '2022年复试理论知识科目大纲':
        print('出了!')
        send()
        break
    else:
        resp = requests.get(url)
        resp.encoding = 'utf-8'
        html = etree.HTML(resp.text)
        news = html.xpath('//*[@id="line_u8_0"]/div/a/text()')[0]
        print(datetime.datetime.now(), '还没')
        time.sleep(30)

使用方法

你可以直接在你的本地运行,但是这样的话要保证你的电脑不会中断,24小时运行,我是直接放到服务器上挂后台跑,其中pyfilename是你python文件的名字,outname.out是指将这个程序的输出结果保存在outname.out中,直接在服务器上:

nohup python -u pyfilename.py > outname.out &

然后就可以挂后台跑了

outname.out中的内容:


立志做一名攻城狮