之前就想搞这个东西,但是一直拖着,直到今早才弄好。
因为登录学校的新系统需要验证码了,所以原来查询信息的登录部分需要做修改,但用的是c++。
同样是用socket获取网页的源码,但是多了个验证码,并且验证码的那个img标签,src是一个固定的地址,然后直接输入那个src,每次图片都不一样。(原来我想得太简单了,我觉得虽然是随机生成,但是图片应该是同一个src。事实证明我错了,又长见识了)
回到正题,我需要做到的是,手动输入验证码,然后登录。
首先,如同请求网页源码一样,对验证码那个src发出请求,下载验证码。
得到的响应是:响应头(Response Header)和响应内容(图片数据)。
响应头就像下图这种(我这是用vs调试截的图):
响应内容,即图片数据,这是不用用字符串来显示的,因为图片文件中常有0x00这种字节,而0x00在字符串里面就会断开。无所谓啊,因为用recv接收响应的时候,可以得到数据的长度,就按这个长度,把所有的数据统统写到文件里面。
所以我就用一个数据结构来存所有接收到数据,如下:
typedef struct tagResponse { char content[16][2048] ; int length[16] ; int recvBytes[16] ; } Response ;
然后我接收到的数据可能是这样的:
content[0]中是Response Header,即响应头。
content[1]和content[2]中就是图片数据。
验证码就在content[1]和content[2]中,这时候不能完全的把content[1]和content[2]结合起来,写到一个文件中,应该注意的是content[1]的前面几个字符可能并不属于验证码数据,我暂时不知道怎么来的。那应该怎么解决的,简单,你先到网页上手动另存为一个验证码图片,然后用2进制查看的工具看看这个文件是什么编码开头的。我这里下载的是jpg,就是以0xff 0xd8 0xff 0xe0开头的,然后我的content[1]中前5个字符是没用的,就从第6个字符开始取,写入文件,验证码就来了。
得到验证码的图片,还要得到响应头中的Cookie,这就从content[0]里面取。
接着带着这个Cookie,验证码,用户名和密码向登录页发送POST请求。
之后,得到登录页返回的Cookies之后,就相当于登录成功了,然后获取想要的东西吧,一定记得带着Cookie。
我只验证了我们学校的网站,如果有什么说的不对的地方,欢迎指出。