该来的总是要来的

0x00.写在前面

  1. 说明:
    本程序使用 python 构建,仅供学习交流使用

  2. 缘由:
    其一:
    大一时想的很好,计划一个学期选一们体育课,分别选了乒乓,排球,网球。这学期适合我的就剩羽毛了,没想到慢了一步,居然没选上……
    其二:

    注:由于学校考场数量有限,本次英语六级报名对有资格报名的学生采取先报先得的原则,报名额满上限为止,请参加英语六级报名的学生提前做好准备!——来自《教务在线主站》

中国人说话有一特点,重点永远放在最后面。如果不是这句话,我是不会萌生写这个程序的想法的……

0x02.思路逻辑

登陆后间隔设定的时间重复查询报名页面是否含有“英语六级”这一关键字,如有则给自己发送邮件(短信),反之 pass……

0x03.代码细节

一共分两步。
第一步,登陆教务在线主站

1
import requests
2
# 仍然使用 requests 这个第三方库
3
4
fjm_url = "http://jwc.sut.edu.cn/ACTIONVALIDATERANDOMPICTURE.APPPROCESS"
5
# 附加码图片对应地址
6
LoginUrl = "http://jwc.sut.edu.cn/ACTIONLOGON.APPPROCESS?mode=4"
7
# post 登陆对应地址
8
9
s = requests.Session()
10
# 会话对象,我们可以跨请求保持一些 cookie
11
12
img = s.get(fjm_url)
13
# get 请求附加码图片
14
with open('fjm.jpg', 'wb') as f:
15
    f.write(img.content)
16
# 保存图片为同目录下的 fjm.jpg
17
18
fjm = raw_input("请输入附加码:")
19
# 此时需要用户的输入
20
21
username = "< 此处替换为学号 >"
22
password = "< 此处替换为密码 >"
23
24
LoginData = {
25
    'WebUserNO': username,
26
    'Password': password,
27
    'Agnomen': fjm
28
}
29
# 封装数据包
30
31
r = s.post(LoginUrl, data=LoginData)
32
# 登陆

第二步,查询报名列表页面是否含有“英语六级”这一关键字

1
bmlb_url = "http://jwc.sut.edu.cn/ACTIONBMSIGNUP.APPPROCESS?mode=2"
2
# 报名列表对应地址
3
u = s.post(bmlb_url, data={"SignUpNO": 60, "Submit": "%CF%C2%D2%BB%B2%BD"})
4
# 查询
5
6
import re
7
# 这是个正则的库
8
9
tag = u"英语六级"
10
if re.search(tag, u.text):
11
    print "可以报名英语六级啦"
12
    send_mail()
13
else:
14
    pass
15
# 查询是否含有“英语六级”这一关键字

上文中send_mail()就是执行发送邮件的操作,需要提前定义好。我是用 163 邮箱发送报警邮件到 qq 邮箱,还能收到短信提醒,何乐而不为

1
def send_mail():
2
    import smtplib
3
    from email.header import Header
4
    from email.mime.text import MIMEText
5
6
    from_addr = '< 此处替换为你的 163 邮箱地址 >'
7
    password = '< 此处替换为你的 163 邮箱授权码 >'
8
    to_addr = '< 此处替换为你的 qq 邮箱地址 >'
9
    smtp_server = 'smtp.163.com'
10
    smtp_port = 25
11
12
    server = smtplib.SMTP(smtp_server, smtp_port)
13
    server.starttls()
14
15
    server.set_debuglevel(1)
16
    server.login(from_addr,password)
17
    msg = MIMEText(u'可以报名英语六级啦', 'plain', 'utf-8')
18
    msg['From'] =from_addr
19
    msg['Subject'] = Header(u'提醒', 'utf8').encode()
20
    msg['To'] = to_addr
21
    server.sendmail(from_addr,to_addr, msg.as_string())
22
    server.quit()

这样一个流程就全部结束了,不过我们得在外面加个循环,让它可以一直执行下去

1
import time
2
3
while (1):
4
    <把第二步代码移到这里>
5
    time.sleep(600)

0x04.更新日志

未完待续……
2017-7-1 20:51:27
不建议采取上述的循环方法,因为一旦发生网络波动或其他不可预测的事故则会报错退出,所以建议使用计划任务(曾经介绍过……)
2017-7-28 08:46:45
提醒方式除了发送邮件,还可以使用Server酱