当前位置:编程学习 > VB >>

编程读取并发送校内网验证码

文/图 绿袖枫雪
大家好,我们又见面了!开篇之前,我先接住上期我在《校内网刷人气工具DIY》一文中丢给大家的砖头,也就是这一次我将要向大家介绍的如何编程读取并发送校内网的验证码。这次就不废话了,我还是走我比较习惯的先实际测试,再分析思路最后讲代码的路子吧,Follow me!
 
测试
       这一步中我们需要读取若干个包含校内网验证码的图片,至于为什么这个验证码一定就在对应的图片里面就不用我解释了吧!上期的文章中已经讲到,在一定时间内连续访问100个页面之后,服务器会发送来一个包含验证码的图片,如图1所示,我们只有输入这个验证码才能继续访问其他的页面。由于这个验证码最终还是通过字符串形式由我们的机器发送给服务器进行验证的,而这个字符串就在这个验证码图片里面,所以我们需要得到这个图片的URL。由于是测试阶段,这里先不讲如何用程序实现了,这里我们直接找到包含验证码图片的页面。上过校内网的人应该知道,每次修改涂鸦板的时候都需要输入正确的验证码才能成功修改涂鸦板,所以我们从这里入手,直接进入修改涂鸦板的页面,如图2所示。
图1
图2
我们先手工获取该处验证码图片的URL。右击该图片,在弹出的菜单中选择“属性”,在弹出的属性窗口中可以看到该图片的URL以及其长和宽,如图3所示。
图3
虽然此URL并不是以常见的图片文件后缀名结尾的,但属性对话框里的“类型”一栏给出的是“GIF图像”。好,我们将该URL复制后粘贴到IE地址栏,回车,可以看到IE里出现的的确是一张验证码图片,长和宽都不变,为42*16pixels,大小在100字节左右,不过图片里面的验证码已经不是“4224”了,如图4所示。此时继续按回车N次,这个图片都不再变化了,并且经过测试,此时输入“4224”服务器会返回验证码错误,正确的验证码是“2352”,输入“2352”,返回“修改涂鸦板成功”。
图4
       测试这里的时候,我心里还有一点担心,如果图1的验证码图片格式或者长宽和修改涂鸦板处出现的验证码图片不相同就没得玩了。当时用VB写了个小程序连续访问了100个页面,然后再做和上面一样的测试,发现结果都一样,只是图片的URL不一样了,该处URL以及关键的网页代码将在代码部分给出。在IE中提交“属性”中显示的URL时出现的新验证码才是正确的验证码。需要注意的是,在提交这个URL之前,原来的验证码就是正确的验证码,提交该URL之后新出现的验证码同样是正确的验证码,但是输入原来的验证码就会返回“验证码错误”。
       读取验证码后,我们还需要让程序将其提交给服务器。请出WPE,操作步骤就不再细写了,不会的看上期文章。在图1所示的页面中输入验证码“5584”,提交,切换到WPE查看截到的封包:
 
POST /validateuser.do HTTP/1.1..
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*..
Referer: http://xiaonei.com/validateuser.
do?id=75**8..
Accept-Language: zh-cn..
Content-Type: application/x-www-form
-urlencoded..
Accept-Encoding: gzip, deflate..
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Maxthon)..
Host: xiaonei.com..
Content-Length: 74..
Connection: Keep-Alive..
Cache-Control: no-cache..
Cookie: 省略
 
id=75**8&userValidateCode=5584&submit=%E7%BB%A7%E7%BB%AD%E6%B5%8F%E8%A7%88
      
       在这个封包里面,关键标题字段有以下三个:Content-Type、Content-Length和Referer。Content-Length是消息体“id=75**8&userValidateCode=5584&submit=%E7%BB%A7%E7%BB%AD%E6%B5%8F%E8%A7%88”的长度,为74。由于在登录时选择“下次自动登录”可以自动保存cookie,所以这里的cookie字段就不用了。Referer字段处是输入正确的验证码后服务器返回的页面URL,也就是说我们在访问ID=75**8这个用户的时候,服务器需要我们输入验证码,所以这个ID在程序中是可以确定的。这样消息体的第一个ID值就解决了,第二个值userValidateCode就是我们输入的验证码,submit值是一个UTF8形式的编码,我用网上的VB风格的函数得到它的GB码是“继续浏览”,也就是验证码输入框右边的那个按钮的Option值(姑且这么说吧)。弄明白了消息体中的几个关键值,在程序中我们只需要再设置好关键请求头、标题字段以及正确的消息体,就可以使用发包的方法让程序自动提交经过分析得到的验证码了(见代码部分)。
       既然测试到的验证码图片都是42×16像素大小,根据我的读取验证码的方法,现在我们需要确定的是每一张验证码图片中的所有像素点处的颜色值,这一测试部分方法很多,没有技术含量,就不写了。我得到的结果是这些图片的像素点的颜色只会出现黑色#000000和白色#FFFFFF。
       另外,在测试的时候会遇到下面这种情况,这是写代码的时候需要考虑到的,不过我现在还不是很懂。在验证码图片上右击选择“图片另存为”时,下载到的验证码图片和网页上显示的是一样的;同时,用代码下载图片时得到的验证码图片和网页上显示的验证码图片不一样,不过输入并提交此时得到的验证码时,服务器返回“修改涂鸦板成功”,输入原来的验证码反而出错。我自己总结出的原因如下:
1)  我用的下载图片的代码就是2006年02期黑防134页的《CMD下下载文件》一文中的代码,它实现起来应该和在IE中手动提交相应URL是一回事,所以在用代码调试时会出现和图4一样的结果。
2)  右击“图片另存为”时,系统用的可能是枚举网页中的对象元素的方法定位到IMG标签,并调用得到的对象的相应方法来实现下载图片的,这种方式下载得到的图片是“原汁原味”的,和网页中显示的图片是一样的。
上述两点原因是我的猜测,有讲的不对的地方希望大家指点。在程序中我使用的还是上面第一点中提到的方法,毕竟得到的新图片中包含的也是正确的验证码,我就没有尝试我还不熟悉的枚举网页对象的方法来获取原始的验证码了,很希望有达人能指点一二。
 
分析思路
这一部分给出的是我“一不小心”想出来的读取验证码的思路和方法,不过需要提前声明的是,我这个方法只适用于读取校内网的验证码,因为校内网验证码是我所见过的图片形式验证码里面最简单的一种,纯数字、无变形、像素点颜色纯黑或纯白,最好不过了。
在这里我介绍的方法是这样的:首先获取N张验证码图片,只要0~9这10个数字在这些图片中全部出现过就可以了。将其中一张图片分为四份(注意不是四等分,每张验证码图片两边都有几个像素宽的多余部分),保证每一份里面出现一个完整的数字,然后分别读取每一份图片里面的白色像素点的个数,读取的时候遇到黑色像素点就跳过,遇到白色像素点就让记录白色像素点个数的变量加1即可,最后得到0~9中每个数字对应的白色像素点个数。
在实际调试的时候,碰到两个不同的数字对应的白色像素点个数一样的情况,比如0和4对应的白色像素点个数都是26,6和9对应的都是28,2和3对应的都是24,所以我们还需要单独对这三组情况进行区别。下面我们先区别2和3,以此为例,另外两组特殊情况大家可以自己设计不同的区别方法,方法不止一种,不过好像没有什么技术含量。
图5和图6分别是程序执行结果的部分截图,为叙述方便,我在图的最上面和最右边加上了一些字符作为横纵坐标值,它们不算在总行数和总列数里面。图中的黑点表示实际验证码图片的该坐标位置处的像素点颜色为黑色,同理,符号“@”表示颜色为白色的像素点,这样就比较形象的将验证码图片以ASCII码的形式表现出来了。
图5
 图6
现在我们对这两幅验证码图片中的数字2和数字3进行区别。上面已经提到过,每一张验证码图片分割后的四份图片中,每一份都包含且只包含一个完整的数字,故接下来的比较都是基于这一分割形成
补充:软件开发 , Vb ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,