8月22日上午9时,CET6级成绩开始查询了。然而,忘记自己准考证号的也不在少数,而我,非常幸运,成为其中一员。仔细想了想,自己的准考证号是不太可能找回来了。
显然,正常渠道,我是不太可能获取到自己的准考证号了。要等到学校下发6级的成绩单或者班级的成绩单,我估计没半个月是见不到成绩了,甚至更久!
与其等那么久,不如想想有什么办法。
准考证的前10位,毫无疑问,我们知道。那么需要解决的也就是后面的5位了。即使是暴力猜测,也不过10000次。
CET6成绩查询的网站是http://cet.neea.edu.cn/cet/,查询流程很简单,输入准考证号、姓名、验证码即可。
通过抓包,我们获取了如下几个API:
HTTP方式 | URL |
---|---|
GET | http://cache.neea.edu.cn/Imgs.do?ik={准考证号}&t=0.6002525141319914 |
返回的内容:
result.imgs("http://cet.neea.edu.cn/imgs/b3d0c1b6987e4295b01e30ccaceed725.png");
通过正则表达式,提取出图片URL即可。
提示:调用该api记得发送GET请求时需要加上相应的cookie。
HTTP方式 | URL |
---|---|
POST | http://cache.neea.edu.cn/cet/query |
提交的内容:
data=CET6_171_DANGCI%2C准考证号%2C姓名&v=验证码
解码一下:
data:CET6_171_DANGCI,准考证号,姓名v:6wbn
提示:该api提交记得带上相应的cookie
现在,CET暴力查询的整体思路,体现在如下几个模块:
A. 图片获取模块 1. 获取随机的准考证号 2. 获取相应的图片文件 大概获取200张左右图片,之后进行人工图片标记 B. 机器学习模块 1. 标记好下载的验证码图片 2. 图片灰度化、二值化、图片切割 3. 图片转特征矩阵,准备好特征向量与分类标签 4. SVM分类算法进行分类 C. 暴力查询模块 1. 根据输入的前10为准考证号,暴力破解后5为准考证号(考场号3位 + 座位号2位) 2. 指定准考证号ID获取指定验证码图片 3. 图片输入机器学习模块,获取验证码值 4. 提交验证码进行查询,获取相应的结果:验证码错误/无结果/非上述两者,查询成功
难点在于如何对验证码进行识别。
通过第一个API接口,编码文件如下所示:
get_images.py
运行上述文件,我们获得了足够多的图片,然后需要做的是手工对图片进行重命名,文件名为验证码的值。
2. 标记好图片之后,我们再写一个python文件将图片进行切割,将切割后的图片放置在以标签命名的文件夹下。
classify_images.py
运行好后,图片文件就自动分好类了。
3.有了分好类的图片,我们需要做的是将图片转换为相应的特征矩阵和对应的分类标签。我们写一个learn_images.py完成这个任务。
learn_images.py
运行该文件,我们可以对标记好的图片文件进行预测,在predict_images下的文件,然后会打印出预测值与正确的标记值。
4.为了方便使用,我们写了一个api接口文件,方便后续的直接调用。
validate_api.py
有了上述的各大文件,我们就可以进行整合工作了。
5.最后的暴力破解模块
force_query.py
使用只需要修改id变量为你中的准考证号前10位数字,并将name变量改为你自己的名字,程序就可以一步步向正确的准考证号逼近了。
程序停止了有2种情况:
1. 报错了 2. 查到了
报错了后,将开始的range(1, 10001)改下,为报错结束最后验证的值,节约下次查询的时间。
运气好,大概10分钟内就可以得到了。当我查询到了6级分数,我已做好了下一次6级报名的准备,祝你们好运!附上我的一张成功截图:
由于时间原因,程序写得仓促,还有较多的较大的改进空间,例如可以改为多线程或者协程加快查询速率,单线程毕竟太慢了。
不过,估计这东西出来感觉离和谐也不远了。两点原因:
对了,我还想所说的是,这个网站的验证码设计真的很人性化,你运行一下附件中的count_word.py就知道了!
有些代码,文章中并没有贴上来,如utils.py文件,因为和要叙述的关联性不强。另外,文章可能有些细节没有照顾到,结合附件的源代码,你就明白了。