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

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

作者: 子衿我心 | 来源:发表于2019-12-29 14:17 被阅读0次

目录

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

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

循环选课

在成功实现了登陆系统,拉取课程列表之后,我们离成功只差最后一步,只需要模拟浏览器,向对应端口发送选课请求即可。
手动在网页上选择任意一门课之后发现,选课请求体结构非常简单,同样为Post请求

{
  'method':'addSpecialitySelect',
  'classId':'xxxx'
}

这里的classID就是上一篇中提到的后台为每个课程标记的ID,并不是大家平时使用的课程号。好在上一篇中,我们已经对每门课的序号和课程ID进行了映射。

基本思路理清后,代码的部分就相对非常简单。

def GrabCourse(courseID,interval=0):
    while(True):
        selectCourse_reqdata={}
        selectCourse_reqdata['method']="addSpecialitySelect"
        selectCourse_reqdata['classId']=str(courseID)
        selectResult = s.post(host+'student/elective/selectCourse.do',selectCourse_reqdata)
        soup = BeautifulSoup(selectResult.content,"html.parser",from_encoding='utf-8')
        for tag in soup.find_all('div'):
            if tag.get('id')=="successMsg":
                print("抢课成功!")
                return
            elif tag.get('id')=="errMsg":   
                if tag.string.find("已经")!=-1:
                    print("您已经抢到该课程啦~")
                    exit()
                elif tag.string.find("错误")!=-1:
                    print("出现错误,添加失败")
                    exit()
                else:
                    print("当前班级已满,仍在为您持续抢课")
            else:
                pass
        if interval!=0:
            time.sleep(interval)

这里的GrabCourse函数接收两个参数,第一个就是课程ID,第二个为一个可调的时间间隔。为了避免对教务系统造成过大负担(防止被查水表),这里默认设置了每次发送选课请求的时间间隔为1秒。

同时对每次选课请求的返回进行一下检验,主要分为四种情况:

  1. 选课成功:理想情况
  2. 已经选课:证明课表这已经选中这门课
  3. 班级已满:抢课系统主要针对的正是这种情况,班级满时需要循环发送请求,等待班级空出位置的瞬间。
  4. 出现错误:多为课程ID填写错误,或者选择了其他院系专业课(没有选课权限)等情况

对每种情况分别处理即可

其他尝试

由于之前拉取课程列表时,尝试通过填写其他院系编号来构造请求体,成功拉取到了其他院系的课表,可知教务系统后端对院系方面审核并不十分严格。因此在选课阶段同样进行了类似的尝试(作死),方法同样是在构造选课请求时,填写其他院系课程的课程ID
结果:返回“出现错误,添加失败”(笑)
可见教务平台至少在选课的时候还是稍微做了一下身份验证。不过至此,整个抢课系统的基本功能已经实现。可以成功登录、获取列表、循环发送选课请求。接下来的工作就是优化人机交互以及断线重连相关功能。

相关文章

网友评论

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

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