背景:
期末考试已经结束好几天了,一些科目的成绩也陆续出来了。本人也是时不时地刷新教务网查看成绩是否有变化,这带给我些许焦虑。出于这个目的,我写程序实现了以下需求:
每隔30分钟启动,监测教务处成绩变化,如有变化,自动发送邮箱,邮箱中包含我的所有成绩信息。
(Ps:本文完全基于四川农业大学教务网)
操作技术点
1. 使用cookies模拟登录
2. 使用python发送邮箱
3. 每隔一段时间启动
实现思路:
1. 使用cookies模拟登录
我们知道,在教务网查看成绩之前是需要登录的,而这种登录实质上是传入了一些cookie,基于这点,我们不难想到模拟这种cookie传入从而实现模拟登录。
进入四川农业大学教务网—输入学号密码----点击登录 后发现网页跳转到另一个url 这说明该登录操作不是动态加载的,这就方便我们进行操作了。
之后再 鼠标右键---检查 -----点击 成绩信息----成绩查询,进行抓包,我们会得到如下的一堆任务。
其中css是页面布局用的 ,png/gif是图片之类的文件,不用关注。抛开这些,里面只剩下了一个非常可疑的任务 sear_ch_xf.asp
单独对他发送请求(可以直接使用 https://spidertools.cn/#/curl2Request)返回一个html页面,通过网页解析,我们拿到了成绩信息,再通过正则表达式进行分析,我最终得到了成绩信息的字符串。
2. 发送电子邮箱到指定账号
这里参见这篇博客 https://blog.youkuaiyun.com/u014481728/article/details/138375387
上面博客中提供的代码修改修改就能用
# 1、连接邮箱服务器
# 连接邮箱服务器:连接邮箱服务器:使用smtplib模块的类SMTP_SSL,创建一个实例对象qqMail
qqMail = smtplib.SMTP_SSL("smtp.qq.com", 465)
# 2、登陆邮箱
# 设置登录邮箱的帐号为:"zhangxiaofan@qq.com",赋值给mailUser
mailUser = "你的邮箱@qq.com"
# 将邮箱授权码"xxxxx",赋值给mailPass,授权码见我提到的博客文章
mailPass = "xxxxxxx"
# 登录邮箱:调用对象qqMail的login()方法,传入邮箱账号和授权码
qqMail.login(mailUser, mailPass)
# 3、编辑收发件人
# 设置发件人和收件人
sender = "你的邮箱@qq.com"
receiver = "收件人的邮箱@qq.com"
# 使用类MIMEMultipart,创建一个实例对象message
message = MIMEMultipart()
# 将主题写入 message["Subject"]
message["Subject"] = Header("成绩更新")
# 将发件人信息写入 message["From"]
message["From"] = Header(f"Robot <{sender}>")
# 将收件人信息写入 message["To"]
message["To"] = Header(f"aaa <{receiver}>")
# 4、构建正文
# 设置邮件的内容,赋值给变量textContent
textContent = "成绩已更新"
# 编辑邮件正文:使用类MIMEText,创建一个实例对象mailContent
mailContent = MIMEText(textContent, "plain", "utf-8")
# 6、发送邮件
# 发送邮件:使用对象qqMail的sendmail方法发送邮件
qqMail.sendmail(sender, receiver, message.as_string())
# 输出"发送成功"
print("发送成功")
3. 将上述代码结合
import requests
from bs4 import BeautifulSoup
import smtplib
import re
# 从email.mime.multipart中导入MIMEMultipart类
from email.mime.multipart import MIMEMultipart
# 从email.header中导入Header类
from email.header import Header
# 从email.mime.text中导入MIMEText类
from email.mime.text import MIMEText
headers = {
//你的headers
}
cookies = {
//你的cookies
}
url = "https://jiaowu.sicau.edu.cn/xuesheng/chengji/chengji/sear_ch_all.asp"
resp = requests.get(url, headers=headers, cookies=cookies)
resp.encoding ='gbk'
datas =BeautifulSoup(resp.text.split('\n')[-1],'lxml').find_all('tr')[5:][:-2]
with open ("C:\\Users\HW\Desktop\q1.txt",'r') as fp: #这是判断成绩信息是否增加
currrent_length = int(fp.read())
if len(datas)>currrent_length:# 如果成绩信息增加了就更新信息,并发送邮件
with open("C:\\Users\HW\Desktop\q1.txt", 'w') as fp:
fp.write(str(len(datas)))
mes = ''
for data in datas:
data = [re.sub(r'\s+', '', item) for item in re.findall('>([^>]+)</td',str(data))]
mes += f'{data[3]}\t{data[9]}分\t绩点:{data[10]}\n'
qqMail = smtplib.SMTP_SSL("smtp.qq.com", 465)
mailUser = "发件人@qq.com"
# 将邮箱授权码"xxxxx",赋值给mailPass #授权码获取见我在上面提到的博客
mailPass = "授权码"
# 登录邮箱:调用对象qqMail的login()方法,传入邮箱账号和授权码
qqMail.login(mailUser, mailPass)
# 3、编辑收发件人
# 设置发件人和收件人
sender = "发件人@qq.com"
receiver = "收件人@qq.com"
# 使用类MIMEMultipart,创建一个实例对象message
message = MIMEMultipart()
# 将主题写入 message["Subject"]
message["Subject"] = Header("成绩更新")
# 将发件人信息写入 message["From"]
message["From"] = Header(f"Robot <{sender}>")
# 将收件人信息写入 message["To"]
message["To"] = Header(f"aaa <{receiver}>")
textContent = mes
mailContent = MIMEText(textContent, "plain", "utf8")
message.attach(mailContent)
qqMail.sendmail(sender, receiver, message.as_string())
运行后邮件发送成功:
至此,我们的python程序就已经编写完成了 。后面的操作是基于win系统,不会再修改代码了。
4. 每隔半小时定时启动
win--->搜索框搜索 “ 任务计划程序 ”---->点击它,弹出以下框体
点击创建任务(红框部分)弹出下面框体
填写名称/点击最高权限运行 ,选项卡切换到触发器,变成如下页面:
点击新建,弹出如下窗体:
按图中红框配置后点击确定,之后切换 操作 选项卡:
点击新建后弹出的窗口中有4个交互,我将其命名为1234:
在1中,我们填写的是python解释器的位置(我的是 D:\anaconda\pythonw.exe )
在2中,我们填写的是 python程序名.py(我的是 python自动化之教务网成绩监听.py )
在3中,我们填写的是该py文件所在文件夹的绝对路径(我的是 D:\code\爬虫练习)
在4中,我们选择的是 启动程序
之后点击 确定--->运行,就可以了。