好友
阅读权限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] 纯文本查看 复制代码 1 2 3 4 5 6 7 8 9 | 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] 纯文本查看 复制代码 01 02 03 04 05 06 07 08 09 10 | 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] 纯文本查看 复制代码 01 02 03 04 05 06 07 08 09 10 11 12 | 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] 纯文本查看 复制代码 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | def get_data_kch_id(zyh_id,yhm):
serch_url = 'http://***.**.***.***/jwglxt/xsxk/zzxkyzb_cxZzxkYzbPartDisplay.html?gnmkdm=N253512&su=' + str (yhm)
data = {
'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] 纯文本查看 复制代码 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | 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] 纯文本查看 复制代码 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 | 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))
|
[Python] 纯文本查看 复制代码 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | 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))
|
写完了简单运行下
嗯还是可以的,至于这个图里的内容有个编号,因为我们获取参数的时候是通过搜索教学班编号完成的 所以在通过代码选课的时候仍然需要这个教学班编号,这个每个学校选课前应该会发个文件,里面就有。
结语
对于不同的学校选课时的参数可能会有细微的差别,各位同学可以对比着自己修改一下
因为楼主是小白,只是简单的学习了下爬虫和python,所以思路可能有些混乱,代码可能有很多问题,希望各位大佬不吝赐教
代码
以下是原代码
code_show.zip
(25.75 KB, 下载次数: 177)
这个代码是楼主前两天选课的时候用的,只是把域名和学号密码用*替换了,大家可能要自己改一下才能用
里面的yhm是学号,mm是密码。 |
免费评分
-
查看全部评分
|