CC~NU抢课脚本

34.jpg
34.jpg

用前说明:

本文章仅对 Web 开发,Python 开发进行探讨,进行实验时请遵守学校的规章制度。
任务自动化本来就是程序员的一大乐趣,无关价值观。

废话

很多人有误区,以为抢课脚本就是像游戏外挂一样,利用什么教务处系统漏洞去搞到课,而事实上抢课脚本只是模拟浏览器和服务器进行交互而已。而它们之间交互的方式是使用 HTTP 协议,换言之你的程序只要通过 HTTP 协议与服务器进行交互,就可以模拟浏览器能完成的事情。

当然,最朴素的抢课脚本应当数按键精灵。但是按键精灵依赖于浏览器的渲染速度,而使用 HTTP 协议交互的脚本可以忽略一切 CSS JS 文件的解析,直接发请求,资源占用和速度都优化了一个量级。

简而言之,由于 HTTP 是无状态协议,所以每次提交请求,服务器无法判断你是否是之前的用户,因此在动态网页中常用 Cookies 来鉴别用户身份,Cookies 是附加在每次 HTTP 请求中用来识别用户身份的数据。

在 Python 中,直接使用 urllib2 默认的 urlopen 是不能处理好 Cookies 的,这里的 urlopen 可以看成是一个能向目标 URL 发请求的对象。所以我们使用 cookielib 来构造一个能处理 Cookies 的 opener。

cookie = cookielib.CookieJar()
handler = urllib2.HTTPCookieProcessor(cookie)
opener = urllib2.build_opener(handler)

以后,我们使用 opener.open(url) 就可以带 Cookies 去发 GET 请求了。

环境要求

  • Python 3
  • selenium
  • chrome
  • chromedriver

登录

首先用 Chrome 分析一下教务系统的逻辑是怎样的,打开 Inspect 然后打开教务处网站


屏幕快照 2018-01-09 14.29.59.png
屏幕快照 2018-01-09 14.29.59.png

12.png
12.png

可以看出,前端一点都不简洁,估计编写代码的人技术不是很高,从文件名可以简单地看出 cas.js 应该是散列函数,应该是处理密码用的。

然后我们手动登录一下,看看登录的请求是怎样的。


132.png
132.png

屏幕快照 2018-01-09 14.47.21.png
屏幕快照 2018-01-09 14.47.21.png

可以看出发送了一个 POST 请求,请求地址是 http://xk.ccnu.edu.cn//xtgl/index_initMenu.html。表单内容有 username、password、j_code 和一堆不知道含义的东西。显然 username 是学号了,password 有经验的可以看出来是的 MD5 散列之后的结果,j_code 是验证码结果。

直接对应填上即可。

post_data = {}
post_data['username'] = username
post_data['password'] = pasw_cas
post_data['lt'] = ''
post_data['_eventId'] = 'submit'
post_data['submit'] = '登录'
post_data = urllib.urlencode(post_data)
opener.open(login_url, post_data)

CAS

既然知道了和 CAS 有关系,可以用 Python 的 cas 模块进行尝试。

pasw_cas = cas.new()
pasw_cas.update(password)
pasw_cas = pasw_cas.hexdigest().upper()

一测试发现,提交的就是密码的 CAS 散列,问题就轻易解决了。当然如果不对,一般来说可以尝试用户名+密码的组合,还有是加上时间戳的组合,最后不行就去逆向 JS 文件吧。

抢课请求

相信到这里很多人已经摸到套路了,无非就是抓一个请求,分析,然后伪造这个请求。
这里发现选课只需要发一个 POST 请求到 http://xk.ccnu.edu.cn//xtgl/,当然也有带上 SID,此外还有一个参数,想必就是课程编号了。

和登录一样,我们构造一个字典,然后用 urllib 中的 urlencode 功能进行编码,最后使用 opener.open(res, elect_post_data) 发送请求即可。

elect_post_data = {};
elect_post_data['sid'] = sid
res = urllib2.Request(elect_url)
opener.open(res, elect_post_data)

如果再套上一个死循环,这个抢课脚本就写完了。当然,肯定是有很多问题的,我们慢慢来解决

Delay

如果直接死循环而不加上延时,服务器多半会挂掉。因为客户端的一个请求对应服务器的一次数据库查询,多半这样的压力学校服务器是受不了的。而且过高的发包很容易被查水表,一般来说 0.5s 到 0.3s 的延时已经足够超越极大部分单身二十年少年的手速。

浏览器伪装

一般的 Web 都是会对 HTTP 的请求头进行检测,以防止一些最简单的爬虫,很幸运的是,教务系统并没有。但是一旦对方的 Web Server 开启了访问记录,很容易把这些 HTTP 请求头为空的请求筛选出来,然后慢慢查水表之类的,所以为了安全起见,我们需要伪造浏览器的请求头。

UA = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36'
Referer = 'http://xk.ccnu.edu.cn/zftal-ui-v5-1.0.2/assets/js/zftal/jquery.extends.contact-min.js?ver=20171211' + sid
X_Requested_With = 'XMLHttpRequest'
res.add_header('User-Agent', UA)
res.add_header('Referer', Referer)
res.add_header('X_Requested_With', X_Requested_With)

解析响应

上面的代码我们只处理了发送请求,而并没有理会响应,这样即使抢到了课,程序还是会继续运行下去。

我们先分析一下响应是怎样的,Chrome 中 Inspect 有一个很好用的功能是 Copy as cURL,可以将这次请求提取为 cURL 命令,方便丢到命令行进行分析。


5.png
5.png

可以看出这是一个 JSON 格式的响应,在 Python 处理 JSON 很方便,我们可以用 json 库中的 response_json = json.loads(response) 将 JSON 字符串转换为一个字典。这样你就可以根据响应来后续处理,例如是微信通知之类的。

注意

  • 不建议在一台电脑上开启多个。
  • 本脚本仅为个人程序开发之练习,切勿随意传播。
  • 改选时间尚未开放,该脚本暂未测试,暂未测试,暂未测试!

致谢:

caoruiy

原文地址:www.iooy.com

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,386评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,142评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,704评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,702评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,716评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,573评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,314评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,230评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,680评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,873评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,991评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,706评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,329评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,910评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,038评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,158评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,941评论 2 355