中国矿业大学抢课脚本
快速开始
建议在虚拟环境下运行,首先安装依赖包
pip install -r requirements.txt
参考配置部分配置好config.yml后,参考demo.py调用模块即可,全部封装为组件,适合二次开发,最后为选课模块效果展示。
具体方法使用可参考demo.py
功能
模拟登录
使用
模拟登录基于flask,并已经部署到了服务器上,并提供了相应接口供使用,该项目将不再开源,下面只提供实现思路。
未来打算用django写个接口方便调用
# Login模块使用
from utils.Login import FastLogin
# 获得一个登录对象
sess = FastLogin(ID, PWD)
# 获得cookie
cookies = sess.get_cookies()
# 获得session
session = sess.get_session()
实现
基于requests,模拟了发包过程,通过分析登录操作可以知道,先get RSA的公钥再get验证码,分析前端加密js可知,是通过rsa对password进行了加密,我们可以用python来模拟,这里没用node.js的环境,全部模拟的,在这耗费了很长时间,其中jsFunction模拟了js中对RSA的加密。由于get的验证码是二进制文件,可以直接将其写入文件中,然后调用本地AI识别,或者人工识别,两个函数在FastLogin中可以自由选择,可以通过config.yml进行设置(服务器端默认AI识别)
# 人工识别
code = get_code_by_self(sessions)
# AI识别
code = get_code_by_ocr(sessions)
config如下
opinions:
AI: true
调用人工识别函数的时候比较有趣,如下,会弹出窗口,然后人工识别

成功获得了cookie

ocr识别的话,如下

只识别了一次,如果识别错误的话,会自动重新登录,直到登录成功
student模块
从用户对教务系统的所有操作这个行为中抽象出Stu对象,可以直接调用,提供以下方法
from utils.student import Stu
stu = Stu(ID, PWD) # 实例化学生对象
stu.getScores(2021, 3) # 获取2021学年第一学期成绩
stu.getCourses(2021, 3) # 获取2021学年第一学期课表
获取成绩
分析抓包即可,页面逻辑比较简单,post后返回的是json数据,解析,保存成了字典,{科目=>[平时分,期末分,总分,学分,绩点]},
因为获得平时分时需要每一科都请求一次,因此速度比较慢!

获取课表
与爬取成绩类似,之后将进行图形化处理。
信息通知
信息通知默认为server酱,付费,可自行更换为其它方式,重写util.ext中的sendMessage函数即可
def sendMessage(_title, _content):
_url = f'https://sctapi.ftqq.com/{SERVER_ADDRESS}.send'
_data = {
'title': _title,
'desp': _content,
}
try:
log('正在发送server酱')
requests.post(url=_url, data=_data)
log('发送成功')
return True
except:
log('发送信息失败')
return False
二次开发示例
新成绩微信通知
可以挂在服务器上,有新成绩微信就会自动提醒,已封装成组件可直接调用
from utils.notice import Notice
notice = Notice(ID, PWD)
notice.ScoreNotice(2022, 1)
配置
直接在full_config.yml更改,重命名为config.yml,id和password为必填项,为教务系统学号和密码
api:
url:
key:
server:
user:
id: '*********'
password: '**********'
opinions:
AI: True
选课模块效果展示
为避免影响正常选课同学选课权益 ,抢课模块不开源,仅展示效果。
以下图片出现的课程,均为过去本人通过正常手段正常选课所得
分类抢课
1: '主修课程',
2: '跨专业本硕一体化拓展课程组',
3: '劳育理论教学',
4: '劳育实践教学',
5: '板块课(体育)',
6: '通识选修课'
体育课

公选课

劳动实践
因本人过去已选修过该类课程,故没有选课成功的提示,只有过程展示

条件选课
可按课程号或教师姓名等多种条件模糊搜索选课

多课程选课
可同时选多门课
kcid = ['Q30127', 'Q11035']

多线程选课
基于py threading模块,可自定义抢课线程数量
rob(self, kcid: list, thread_num: int, xid: int)