python模拟登录教务系统
闲来无聊,自学了python基础,便试着用python模拟登录四川大学的本科教务管理系统
一. 浏览器登录
-
打开教务系统首页,F12进入控制台,查看cookie,只有一个JSESSIONID,这个cookie就是后续我们登录教务系统的凭证,也是唯一的凭证。
-
输入学号、密码(aaa123456)、验证码,尝试登录,
可以看到,这三个数据以post请求,表单的形式进行提交,该请求url是:http://zhjw.scu.edu.cn/j_spring_security_check,j_captcha和j_username都以明文的形式传输。 -
j_password是密码经过md5算法加密生成的,具有唯一性。
什么,你问我怎么知道是md5加密的?因为在我清除cookie,多次登录后发现j_password的值都一样,所以怀疑是固定算法生成的,且不包含时间戳等可变信息。然后我就在控制台找到了http://zhjw.scu.edu.cn/js/md5/md5.js这个js文件。
于是用python验证:完全一样!
二. python实现
python代码主要实现三部分:登录首页获得cookie、获取图片验证码地址、提交表单数据。
# -*- coding: utf-8 -*-
import requests
import hashlib
from PIL import Image
import lxml.etree as etree
USERNAME = ""
PASSWORD = ""
log_url = "http://zhjw.scu.edu.cn/login?"
figure_url = 'http://zhjw.scu.edu.cn/img/captcha.jpg'
post_url = "http://zhjw.scu.edu.cn/j_spring_security_check"
"""
创建session并保存cookie,这里我没有设置header,因为我尝试手动加上header和去掉header
两种方式都能成功登录
"""
session = requests.Session()
session.get(url=log_url)
# 获取验证码
picture = session.get(url=figure_url).content
with open('captcha.jpg', 'wb') as f:
f.write(picture)
picture = Image.open('captcha.jpg')
picture.show()
captcha = input('请输入验证码:')
# 实际登录:md5加密、构建表单,提交表单
md5 = hashlib.md5(PASSWORD.encode('utf-8'))
data = {'j_username': USERNAME,
'j_password': md5.hexdigest(),
'j_captcha': captcha
}
resp = session.post(url=post_url, data=data)
# 通过xpath查找登录成功后html文档中的学生信息,如果可以输出姓名则登录成功
selector = etree.HTML(resp.text)
user_name = selector.xpath('''/html/body/div[@id="navbar"]/div[@id="navbar-container"]/div[@role="navigation"]/
ul[@class="nav ace-nav"]//li[@class="light-blue"]//span[@class="user-info"]/text()''')
print("登录成功:"+ user_name[1].strip())
三. 写在最后
验证码部分我尝试调用阿里云免费的图形验证码识别API,但是识别准确率不太高,遂保留手动识别。最后代码封装,实现获取本科历年课程成绩。
# -*- coding: utf-8 -*-
import json
import hashlib
import lxml.etree as etree
import requests
from PIL import Image
class CreateSession:
def __init__(self, username, password):
md5 = hashlib.md5(password.encode('utf-8'))
self.username = username
self.password = md5.hexdigest()
self.session = requests.Session()
self.session.get("http://zhjw.scu.edu.cn/login?")
def get_code(self):
while True:
figure_url = 'http://zhjw.scu.edu.cn/img/captcha.jpg'
picture = self.session.get(figure_url).content
with open('captcha.jpg', 'wb') as file:
file.write(picture)
picture = Image.open('captcha.jpg')
picture.show()
captcha = input('请输入验证码:')
if len(captcha) != 0:
break
return captcha
def login(self):
post_url = "http://zhjw.scu.edu.cn/j_spring_security_check"
bad_credit_url = "http://zhjw.scu.edu.cn/login?errorCode=badCredentials"
bad_captcha_url = "http://zhjw.scu.edu.cn/login?errorCode=badCaptcha"
data = {'j_username': self.username, 'j_password': self.password, 'j_captcha': self.get_code()}
resp = self.session.post(post_url, data=data)
if resp.url == bad_captcha_url:
print("验证码错误!")
return self.login()
elif resp.url == bad_credit_url:
print("用户名或密码错误!")
exit()
else:
print("登录成功!")
selector = etree.HTML(resp.text)
user_name = selector.xpath('''/html/body/div[@id="navbar"]/div[@id="navbar-container"]/div[@role="navigation"]/
ul[@class="nav ace-nav"]//li[@class="light-blue"]//span[@class="user-info"]/text()''')
print(user_name[1].strip())
def query_score(self):
# 成绩查询
query_url = "http://zhjw.scu.edu.cn/student/integratedQuery/scoreQuery/allPassingScores/callback"
response = self.session.get(query_url, cookies={"selectionBar": "1379870"})
semester = json.loads(response.content.decode("utf-8"))["lnList"]
for i in semester:
for j in i["cjList"]:
print(j["courseName"] + ": " + j["cj"])
if __name__ == '__main__':
USERNAME = ""
PASSWORD = ""
f = CreateSession(USERNAME, PASSWORD)
f.login()
f.query_score()
学校的教务网站还是很容易实现模拟登录的,主要在于登录站点只有一个cookie,且账号密码的验证机制比较简单,很适合我这种初学者学习。
立个flag,下一步实现模拟登录csdn!