暴力查询四六级准考证号——真的很暴力

Author Avatar
Reborn 8月 23, 2018
  • 在其它设备中阅读本文章

参考:http://www.freebuf.com/articles/database/145261.html

背景

昨天有个朋友说准考证没带回来,问我能不能帮她查下准考证号,我突然想起了今年2月份穷举的四级准考证,于是就翻出来试试。

当时我对源码进行了一些修改,不过一年前我还没搭建博客,如今也算有个机会对当时的学习做个记录和总结。

昨天我也继续对源码进行了一番改进,改的都非常简单,认真阅读了原作者那部分修改前的源码就肯定能看懂。

要懂得感激

首先,感谢@FlashYo提供的源码,让我也学习了不少东西。里面链接原本是失效了的,我又去问了@FlashYo,想看下utils.py是怎么写的,他想都没想就分享了,我表示很感激。

于是呢,我就开始了第一次阅读 Python 代码的经历(其实这也是我第一次接触 Python ),代码看完之后感觉也不难,@FlashYo的代码写的很有条理,他的文章也有很详细的代码说明。

但由于原文说不经允许禁止转载,我也尊重作者,所以这里就不贴他的代码和文章内容啦!有兴趣的可以去上面提供的参考链接看。

2018-08-25更新:已获得作者授权引用他的文章内容,感谢@FlashYo🌚

那么……我这篇博文是写什么的呢?

自己的收获

那当然是写自己的收获啦!(说了那么多也该进入正文了嗯。。。)

其实我对原程序做了点改进🌚

在说我改进了什么之前,先给大家科普一下四六级准考证号的组成吧!

四六级准考证号的组成元素

这东西百度谷歌随便都查的到,一张图带你了解英语六级准考证号组成~

CET-ID

六级准考证号一共由15位组成:

  1. 前5位是学校代码
  2. 第6位是学校的校区代码 大学英语四六级考试院校考点代码大全(前6位)
  3. 第7-8位是考试年份

    如2014年考试此处应为14,14代表2014年。

  4. 第9位是该年中第几次四六级考试

    上半年是第1次,下半年是第2次,那么2014年12月就是2。

  5. 第10位是四六级类别,四级是1,六级是2。
  6. 第11-13位是考场号

    比如你在100考场的,那就是100,14考场的就是014。

  7. 第14-15位是座位号

    如果你是01号座位,那就是01,29号就是29 。

学校代码校区代码查不到的直接随便问一个自己学校的考四六级的同学问一下就好了,那么前6位已经得到了;7~10位就不用我说了吧,自己是什么时候考什么试对应就好了。前10位确定好了,所以接下来不知道的其实就只剩下考场号座位号

改进1: 支持自定义试室范围和座位号范围(2018年2月…忘了具体啥时候了哈哈哈)

其实一开始的想法是自定义座位号范围,因为我想到很多学校一间试室都不会坐99个人。原程序的座位号是从 1 跑到 99 的,没法自定义范围,这样的话就会浪费很多时间去查询很多不存在的准考证号。

于是我做了以下改进:
既然要自定义座位号范围,那么就要把试室号和座位号拆开了,于是我顺便把自定义试室范围也搞了,这个很简单,加个for循环以及改下函数参数就好了。

原代码:

myid = "你的准考证号前10位{id:05d}"
...
for num in range(1, 10001):
    query_text =send_query_until_true(num)
...

改进后:

myid = "你的准考证号前10位{room_id:03d}{seat_id:02d}"
...
# 试室范围:1~999,试室人数 1~40
    for room_num in range(1, 999):
        for seat_num in range(1, 40):
            query_text = send_query_until_true(room_num, seat_num)
...

记得把send_query_until_true()函数的参数也修改成room_num, seat_num

改进2: 让程序遇到 Error 不中断执行(2018-08-22 更新)

@FlashYo在他的文章最后讲过,程序停止了不是报错就是查到了,我当时好奇会什么报错咧?

跑了一段时间后终于中断了,看了一下终端信息,原来是requests模块抛出的异常。后面又试了好几次中断,然后跑自己的准考证号时遇上了网络高峰期,尤其是这渣网络,简直疯狂断线,不带重连那种😂。终于忍无可忍,卷起袖子就开撸!

(咳~不能那么粗鲁,要文明🌚(逃~

直接上代码:

...
# 2018-08-22 更新 捕捉网络异常实现程序遇到 Error 不中断执行
    while True:  # 一直循环,直到访问站点成功
        try:
            # 以下except都是用来捕获当requests请求出现异常时,
            # 通过捕获然后等待网络情况的变化,以此来保护程序的不间断运行

            # 此处写requests请求
            ...
            ...查询准考证的函数`send_query_until_true(...)`的内容...
            ...

        except requests.exceptions.ConnectionError:
            log_info('Unfortunitely -- ConnectionError Happened, please wait 3 seconds')
            time.sleep(3)
        except requests.exceptions.ChunkedEncodingError:
            log_info('Unfortunitely -- ChunkedEncodingError Happened, please wait 3 seconds')
            time.sleep(3)
        except:
            log_info('Unfortunitely -- An Unknow Error Happened, Please wait 3 seconds')
            time.sleep(3)

Umm…我一口气把所有异常都捕捉了哈哈哈!!!这个代码也很简单,捕捉到异常就等待3秒,然后尝试重新跑 上一个 准考证号,有种断线重连的效果。

log_info(*arg)是我自定义的一个函数,用于在终端输出信息的同时把信息存到文件中,方便后期查看(好吧,其实是避免电脑突然蓝屏或者什么原因重启导致的终端记录丢失,那我又要重新跑,多亏哦!)。

真丶写收获

时间问题,先在手机便签写着,写完马上补上,大家不要太期待哈哈哈🌚

战果

完成这些之后,终于能 全自动 跑了!!全自动!!!

Oh, Yeah!妈妈再也不用担心我的程序突然中断了!!

昨天晚上,噢不,今天凌晨😂3点多,帮我的朋友跑出了她的准考证号,跑了好久哦,好几个小时,还好全自动🌚。。。

嗯…顺便在这里再次恭喜一下你过了六级吧👍👏 @念念 ,被我吊了一手胃口刺激不🌚?

(不要问我为什么不查自己的,因为我还没考哈哈哈!)