这个其实是大一暑假临近选课的时候做的,因为最近太闲了,所以整理了一下水一篇文章。

验证码识别部分用的 go 写的,抢课部分用的 js。正好是当时正在学习 go,然后 js 处理图片也不是很方便,所以就用 go 做验证码识别了。

验证码识别

先是获取样本,就是获得一个验证码,然后手动输入验证码,然后提交登录表单判断是否正确,如果正确的话就把验证码保存下来。这部分用 go 调的 phantomjs 来做的模拟登陆。现在想想其实根本不需要用 phantomjs 的,直接发请求就行了,golang 还自带 cookiejar,就一个外部库都不需要用了。

大概是这么个状态

当时手动打了半个小时的码,才攒了不到两百个验证码,结果之后石乐志把os.Open写成了os.Create导致所有样本全丢了。

先做二值化和滤波。然后裁剪成单个字母。

然后识别部分非常简单,对于教务系统这种只转了一点角度,没有做任何形变的字母图片,如果用 CNN 的话应该随便用一个模型就能有很好的效果了。但是那就又变成调库了。但是手写起来又很麻烦。所以直接用 kNN 来预测了。在有 200+样本的时候单个字符有 80%+的正确率。在有 2k+样本的时候单个字符就可以达到 95%+的正确率了。

然后给把预测图片做一个命令行接口,供方便调用。可是后来还是觉得不方便,每次都要读取样本数据很麻烦,所以又做了一个 web server,可以通过 post 请求上传图片来调用识别。这样一来调用起来就更方便了。

验证码识别的代码放在这里。初学 go 代码还是比较丑陋。

自动抢课

抢课其实就是发请求。主要是教务系统各种奇葩参数非常蛋疼。字符集还不是 utf8。不知道每个参数是什么作用,所以只好慢慢测。不过多亏了有个同学比较有耐心,把 普通选课部分的接口 都扒了。所以就直接哪来用了。

因为开始就想好了做并发抢课,用 node 事件模型来做并发还是很方便的。并且用 yaml 来配置选课信息,很方便的可以起多个实例同时给室友一起抢。如果大家都是同一节课就一次只要一个人去帮大家答到就好啦。

然后放在学校实验室的机房里挂机就好啦。最终效果大概是这样的。

抢课部分的代码在这里

虽然没有什么难度。但是还是想分享一下。