好友
阅读权限 10
听众
最后登录 1970-1-1
血海修罗
发表于 2023-12-28 16:47
本帖最后由 血海修罗 于 2023-12-30 11:30 编辑
某方正教务系统抢课
前言 今年年初学习了shiyier大佬的帖子:女朋友教务系统抢课老抢不上,写个代码解决这个问题,搞定了登陆的问题,但由于大佬没有给出抢课的代码,身为苦逼大学生的我在暑假简单学习了下python和爬虫,自己实现了抢课的功能,并在近几天经过了实测,赶在今年结束前与大家分享一下思路。
功能实现
1.实现登录 具体思路请参考下帖:
女朋友教务系统抢课老抢不上,写个代码解决这个问题
https://www.52pojie.cn/thread-1739086-1-1.html
(出处: 吾爱破解 论坛)
2.实现选课
即本帖内容
分析网页
选课嘛,我们先随便选一门看看有什么东西
很明显的可以看到浏览器发送了两个请求,那我们就看看这俩分别有哪些参数
可以看到无论是第一个请求还是第二个请求都有jxb_ids、kch_id、zyh_id这三个参数,很明显这仨很重要,那就想方设法的获取一下这仨参数
获取zyh_id和 xkkz_id
不管这几个参数多复杂,我们先去网页源代码看看,万一真的简单的放在了源代码里呢?
经过楼主的一通操作,发现源代码里的确有存放其中的几个参数,那就是zyh_id和xkkz_id ,很明显zyh_id和xkkz_id 就是代表所选的课程分属的版块,那这个简单的爬一下源代码就可以了
下面是代码,里面的yhm是你的学号
[Python] 纯文本查看 复制代码
#获取zyh_id
def get_zyh_id(yhm):
zyh_id_url = 'http://***.**.***.***/jwglxt/xsxk/zzxkyzb_cxZzxkYzbIndex.html?gnmkdm=N253512&layout=default&su=' + str(yhm)
response = session.get(url=zyh_id_url)
response.encoding = 'utf-8'
content = response.text
tree = etree.HTML(content)
zyh_id = tree.xpath('//input[@id="zyh_id"]/@value')
return zyh_id[0]
[Python] 纯文本查看 复制代码
#爬取xkkz_id
def course_sort(yhm):
sort_url = 'http://***.**.***.***/jwglxt/xsxk/zzxkyzb_cxZzxkYzbIndex.html?gnmkdm=N253512&layout=default&su=' + str(yhm)
response = session.get(url=sort_url,headers=headers1)
response.encoding = 'utf-8'
content = response.text
tree = etree.HTML(content)
course_sort_id = tree.xpath('//a[@role="tab"]/@onclick')
return course_sort_id
[Python] 纯文本查看 复制代码
#因为xkkz_id不是每次都会发生变化,所以这里把xkkz_id写入到文件里,不用每次都爬取
def get_course_sort_id_true(list):
pattern = r"queryCourse\(this,'(?:[^']*)','(\w+)'"
extracted_texts = []
for text in list:
match = re.search(pattern, text)
if match:
extracted_text = match.group(1)
extracted_texts.append(extracted_text)
with open("courese_sort_id.txt", "w") as file:
for item in extracted_texts:
file.write(item + '\n')
获取jxb_ids和kch_id
这俩在网页源代码里没有,那么就先搜一下
于是就找到了这串代码
很明显基本上所有的参数都是在这个函数里生成的,但是楼主水平不够,不知道怎么通过这个函数获取这些参数,所以采用了一个比较迂回的办法,有兴趣的大佬可以看看怎么从这里获得参数。
下面是楼主的思路:
我们知道选课可以搜索,搜索就必然要返回给我们数据,我们还知道,每门课程都有一个与其唯一对应的教学班编号,那我们就搜一下呗
如图所示,搜索之后给了我们两条数据,打开一看,里面就正好有我们想要的jxb_ids和kch_id
那知道这俩参去哪获取了,同样的去爬一下就可以了,不同的是这里的参数是通过搜索获得的,所以需要通过两个post请求获得
[Python] 纯文本查看 复制代码
#获取kch_id
def get_data_kch_id(zyh_id,yhm):
serch_url = 'http://***.**.***.***/jwglxt/xsxk/zzxkyzb_cxZzxkYzbPartDisplay.html?gnmkdm=N253512&su=' + str(yhm)
data = {
#这里的filter_list是你搜索的教学班编号,下同
'filter_list[0]':filter_list,
'rwlx':rwlx,
'xkly':'0',
'bklx_id':bklx_id,
'sfkkjyxdxnxq':'0',
'xqh_id':'05',
'jg_id':'07',
'njdm_id_1':'2022',
'zyh_id_1':str(zyh_id),
'zyh_id':str(zyh_id),
'zyfx_id':'wfx',
'njdm_id':'2022',
'bh_id':'20220809113',
'bjgkczxbbjwcx':'0',
'xbm':'1',
'xslbdm':'wlb',
'mzm':'01',
'xz':'4',
'ccdm':'3',
'xsbj':'4294967296',
'sfkknj':'0',
'sfkkzy':'0',
'kzybkxy':'0',
'sfznkx':'0',
'zdkxms':'0',
'sfkxq':'0',
'sfkcfx':'0',
'kkbk':'0',
'kkbkdj':'0',
'sfkgbcx':'0',
'sfrxtgkcxd':'0',
'tykczgxdcs':'0',
'xkxnm':'2023',
'xkxqm':'12',
'kklxdm':kklxdm,
'bbhzxjxb':'0',
'rlkz':'0',
'xkzgbj':'0',
'kspage':'1',
'jspage':'10',
'jxbzb':''
}
response = session.post(url=serch_url,data=data,headers=headers1)
kch_id_1 = response.json()
with open('kch_id_1.json', 'w', encoding='utf-8') as fp:
fp.write(str(kch_id_1))
[Python] 纯文本查看 复制代码
# 取课程jxb_ids
def get_jxb_ids(yhm,kch_id):
choice_url = 'http://***.**.***.***/jwglxt/xsxk/zzxkyzbjk_cxJxbWithKchZzxkYzb.html?gnmkdm=N253512&su=' + str(yhm)
data_beggin = {
'filter_list[0]':filter_list,
'rwlx':rwlx,
'xkly':'0',
'bklx_id':bklx_id,
'sfkkjyxdxnxq':'0',
'xqh_id':'05',
'jg_id':'07',
'zyh_id':str(zyh_id),
'zyfx_id':'wfx',
'njdm_id':'2022',
'bh_id':'20220809113',
'xbm':'1',
'xslbdm':'wlb',
'mzm':'01',
'xz':'4',
'ccdm':'3',
'xsbj':'4294967296',
'sfkknj':'0',
'sfkkzy':'0',
'kzybkxy':'0',
'sfznkx':'0',
'zdkxms':'0',
'sfkxq':'0',
'sfkcfx':'0',
'bbhzxjxb':'0',
'kkbk':'0',
'kkbkdj':'0',
'xkxnm':'2023',
'xkxqm':'12',
'xkxskcgskg':'1',
'rlkz':'0',
'kklxdm':kklxdm,
'kch_id': str(kch_id),
'jxbzcxskg':'0',
'xkkz_id': xkkz_id,
'cxbj':'0',
'fxbj':'0'
}
response = session.post(url=choice_url,data=data_beggin,headers=headers1)
course = response.json()
with open('course.json', 'w', encoding='utf-8') as fp:
fp.write(str(course))
with open('course.json', 'r', encoding='utf8') as f:
jxb_id = f.read()
jxb_id = jxb_id.replace("'", '"')
jxb_id = jxb_id.replace("False", '"False"')
jxb_id = jxb_id.replace("True", '"True"')
jxb_id_data = json.loads(jxb_id)
jxb_id_true = jsonpath.jsonpath(jxb_id_data, '$..do_jxb_id')
return jxb_id_true[0]
完成选课
其他的的参数就无伤大雅了,例如xkxnm代表的是学年,xkxqm代表的是学期,以我们学校为例,今年是2023学年,03是上学期,12是下学期,选课前稍微修改一下就可以了
那么我们回到分析网页的第一张截图
选课时发了两个请求,那我们也发送两个请求,实现代码如下
[Python] 纯文本查看 复制代码
#发送第一次请求
def choice_course_1(yhm,jxb_ids,kch_id,zyh_id):
course_url_1 = 'http://***.**.***.***/jwglxt/xsxk/zzxkyzb_cxXkTitleMsg.html?gnmkdm=N253512&su=' + str(yhm)
data = {
'jxb_ids': str(jxb_ids),
'xkxnm': '2023',
'xkxqm': '12',
'bj': '7',
'kch_id': str(kch_id),
'njdm_id': '2022',
'zyh_id': str(zyh_id),
'kklxdm': kklxdm
}
response = session.post(url=course_url_1,data=data,headers=headers1)
course = response.json()
with open('choice_course_1.json', 'w', encoding='utf-8') as fp:
fp.write(str(course))
#这里写入course是为了判断是否选课成功
[Python] 纯文本查看 复制代码
#发送第二次请求
def choice_course_2(yhm,jxb_ids,kch_id,zyh_id):
course_url_2 = 'http://***.**.***.***/jwglxt/xsxk/zzxkyzbjk_xkBcZyZzxkYzb.html?gnmkdm=N253512&su=' + str(yhm)
data = {
'jxb_ids': str(jxb_ids),
'kch_id': str(kch_id),
'rwlx': rwlx,
'rlkz': '0',
'rlzlkz': '1',
'sxbj': '1',
'xxkbj': '0',
'qz': '0',
'cxbj': '0',
'xkkz_id': xkkz_id,
'njdm_id': '2022',
'zyh_id': str(zyh_id),
'kklxdm': kklxdm,
'xklc': '1',
'xkxnm': '2023',
'xkxqm': '12'
}
response = session.post(url=course_url_2,data=data,headers=headers1)
course = response.json()
with open('choice_course_2.json', 'w', encoding='utf-8') as fp:
fp.write(str(course))
#这里写入course是为了判断是否选课成功
写完了简单运行下
嗯还是可以的,至于这个图里的内容有个编号,因为我们获取参数的时候是通过搜索教学班编号完成的 所以在通过代码选课的时候仍然需要这个教学班编号,这个每个学校选课前应该会发个文件,里面就有。
结语
对于不同的学校选课时的参数可能会有细微的差别,各位同学可以对比着自己修改一下
因为楼主是小白,只是简单的学习了下爬虫和python,所以思路可能有些混乱,代码可能有很多问题,希望各位大佬不吝赐教
代码
以下是原代码
code_show.zip
(25.75 KB, 下载次数: 106)
这个代码是楼主前两天选课的时候用的,只是把域名和学号密码用*替换了,大家可能要自己改一下才能用
里面的yhm是学号,mm是密码。
免费评分
查看全部评分