美文网首页
从零搭建教务抢课系统(一)

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

作者: 子衿我心 | 来源:发表于2019-12-26 19:10 被阅读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获得相关信息(类似爬虫),或发送选课请求等均可。

    相关文章

      网友评论

          本文标题:从零搭建教务抢课系统(一)

          本文链接:https://www.haomeiwen.com/subject/xfploctx.html