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

457 阅读2分钟

目录

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

Github链接: github.com/njuwuyuxin/…

获取选课列表

在研究了教务网的js代码以及抓包分析之后,发现教务网拉取专业选课列表的接口接收不同数量的参数(有默认参数) 专业选课页面的加载逻辑为,初次进入页面自动发送一条post请求,请求体为

{
  'method':'specialityCourseList'
}

该请求只包含调用的方法名,其余均为默认参数,用来拉取默认显示的课程列表

当用户在下拉选单中手动选择某项之后,会向同一端口再次发送一条post请求,请求体为

{
  'method':'specialityCourseList',
  'specialityCode':'221',
  'courseGrade':'2016
}

这次请求体中包含了所在专业的专业编号,以及对应年级

解析网页获得课程列表

按照请求格式构造好请求体中,response返回的HTML文档就是包含了课程列表的页面 这里使用了Beautiful Soup进行解析,可以看到课程列表是以、 标签的形式进行显示,按对应格式解析即可

soup = BeautifulSoup(courseList.content,"html.parser",from_encoding='utf-8')
soup = BeautifulSoup(courseList.content,"html.parser",from_encoding='utf-8')
trs = soup.find_all('tr',{'class':'TABLE_TR_01'})
print("序号\t课程号\t\t课程名\t\t\t学分\t学时\t类型\t开课院系")
for tr in trs:
    tds = tr.find_all('td')
    courseNo = tds[0].find('a').find('u').string
    if(tds[1].string.__len__()<=7):
        print(str(trs.index(tr)+1)+'\t'+courseNo+'\t'+tds[1].string+'\t\t'+tds[2].string+'\t'+tds[3].string+'\t'+tds[4].string+'\t'+tds[6].string)
    else:
        print(str(trs.index(tr)+1)+'\t'+courseNo+'\t'+tds[1].string+'\t'+tds[2].string+'\t'+tds[3].string+'\t'+tds[4].string+'\t'+tds[6].string)
    click_td = tr.find('td',{'onclick':True})
    if click_td==None:
        courseIdList.append("")
        pass
    else:
        # print(click_td['onclick'])
        js = click_td['onclick']
        args = js.split(',')
        courseID = args[4][0:5]
        courseIdList.append(courseID)

由于教务网后端较为特殊,选课的请求体中课程id有单独编号需要提取,而不是使用课程编号(后文有讲),因此额外做了一些解析,HTML解析这里不具有普遍参考价值.

获取的课程列表展示如下:

16734657-21ed6aa2ccdb6724.png

参考资料

Beautiful Soup4 中文文档