从零搭建教务抢课系统(一)

2019-12-26  本文已影响0人  子衿我心

目录

(一)核心功能:模拟登陆
(二)使用Cookie进行模拟登录
(三)获取教务网选课列表
(四)循环选课
(五)断线重连

Github链接: https://github.com/njuwuyuxin/CourseGrabber

一、前言

响应群里学弟学妹号召,心血来潮想做一个南大教务网的抢课系统。在仔细研究了一下教务平台的js代码之后,发现几乎没有什么防护措施,于是便开始着手尝试起来。

抢课系统的主要思路无非就是以下几步:

  1. 模拟教务平台的网页登录,获取session
  2. 登入平台后拉取各个课程列表
  3. 找到对应课程编号,构造选课请求体,循环发送

为了方便调试检验,还使用了wireshark进行简单抓包(可省略),有需要的小伙伴可以自行下载

二、模拟登陆

首先进入教务网登陆界面,尝试一次普通登录


登录请求体

可以发现登录的请求体主要由四个表项组成,returnUrl暂无具体含义,默认为null,其余均为用户提交表单。
这里唯一比较棘手的一点是验证码的获取。

验证码获取

南大教务平台的验证码是通过向后端jsp请求获得。因此在代码里我们同样用模拟浏览器的方式进行请求。

#首先创建一个session
session = requests.session()

#取得验证码图片
now_time = str(int(time.time()))
pic_url = host + 'ValidateCode.jsp'
pic = session.get(pic_url).content
im = Image.open(BytesIO(pic))    #直接打开图片
    im.show()
filename = '' + now_time + '.jpg'  
with open(filename, 'wb') as f:
    f.write(pic)

这里首先创建了一个session,确保获取验证码和登录请求为同一个session,向对应jsp请求,将请求获得的图片保存在本地。
之后尝试使用了ocr进行验证码的自动识别,由于验证码干扰严重,OCR无法识别,因而放弃

#尝试使用OCR自动识别验证码,但是由于验证码干扰较多,不能正确识别,因此采用手动输入方式
# img = Image.open(filename)
# img=img.convert('L')
# vcode = pytesseract.image_to_string(img)  # 使用ocr技术将图片中的验证码读取出来
# time.sleep(0.3) 
# print(vcode)

OCR无法自动识别,那么我们只能采用手动输入验证码的方式,每次登陆时根据获取到本地的验证码进行输入,登陆后自动删除临时图片。
同时发现验证码大约有100秒有效时间,因此需及时输入,否则验证码过期需要重新获取

登录请求体构造

之后我们就可以构造登录请求体,这里为了方便测试,可以选择性读取存储用户信息的配置文件,也可以控制台进行输入

login_data={}
files = os.listdir()
if "user.cfg" in files:
    with open("user.cfg",'r') as f:
        for line in f:
            items = line.split(":")
            items[1]=items[1].replace('\n','').replace('\r','')
            login_data[items[0]]=items[1]
else:
    print("请输入用户名")
    login_data['userName']=input()
    print("请输入密码")
    login_data['password']=input()
        
login_data['retrunURL']="null"
print("请输入验证码(Please enter the ValidateCode)")
vcode=input()
os.remove(filename) #输入完验证码后自动删除本地图片   
login_data['ValidateCode']=vcode

发送登录请求

构造好请求体之后,我们将对应post请求发送到后端端口即可,这里由于无论登陆成功或失败,都会返回200表示请求成功,并不代表登陆成功。而返回的response分别对应错误页面的html和成功页面的html,因此这里简单对response长度进行判断来判断是否登陆成功。

#发送登录请求
response = session.post(host+"login.do",login_data)
if response.content.__len__() > 1100:
    print("登陆成功!")
    return True
else:
    print("登录失败,请检查账号密码及验证码")
    return False

输入完用户信息后,成功登录后,wireshark抓包可以看到对应数据包


登陆成功

打印请求体后,可以发现正是教务平台登陆成功后的主页的html,至此,抢课系统的核心登录部分已经完成。之后可以解析HTML获得相关信息(类似爬虫),或发送选课请求等均可。

上一篇下一篇

猜你喜欢

热点阅读