首先申明:历时八天,本文作者(在多位好友的帮助下)已经成功破解该验证码成功率73%,但是出于网络安全与知识产权等因素(破解只是兴趣,不能咂人家饭碗),不会提供完整源代码。仅发布破解的思路和部分代码。如有转载请告知原作者,关于本文,原作者拥有最终解释权。
0.目录:
- 破解思路分析
- 研究资料分享
- 图像计算处理算法
- 模拟鼠标轨迹
- 破解成功。
1.破解思路分析
该验证码的在百度搜索极验即可找到。目前应用与6.5w家网站,,是目前相当安全的第二代验证码,比12306的好看而且实用多了。好夸完了,咱们来谈谈弱点。
在爬虫届的终极大招就是phantomjs(无界面浏览器)。有意思的是他其实是用来做自动化测试的,那么能自动化测试就能自动化抓取(大雾)so。因为特别好用就被用来做爬虫的工具了。他具有截图鼠标键盘模拟获取源代码等方便的功能,想进一步学习请移步:http://phantomjs.org/api/webpage/method/send-event.html
整体思路与流程:
1:获取截图数据
用phantomjs,首先打开这个网址,然后自然可以捕获到源代码。发现是需要验证,则截取整个界面的屏幕,一般而言每次出现验证码的位置是固定的,则也可以通过像素点得出。这时候能获取到第一张图:然后使用鼠标点击功能,点第一张图中的按钮部分,则会出现下一张图的样子,很简单,再截图一次则获取到图二(不好排版你们意会即可)。
2:图像处理算出需要位移的距离
然后运行图像解析算法,其实很简单,两个图片截图的位置是一样的,所以两个图的差异点只会是出现深色的区域和从左右往右的那个方形滑块。因为要拖动的距离肯定大于60个像素,所以,对两张图片做一个二值化处理就是颜色不变的像素点重新设置为白色,而颜色变化的点设置为黑色,就可以得出下面的图三。然后再从左往右的一排排的进行扫描。寻找第一次出现的列其中包含的黑色像素点比较多(约超过30个像素点)则可以认为是到了第一个区域。然后再从右往左的扫描,也会发现一个新区域,然后判定两个区域哪个区域大以及那个区域颜色深,再取中间点,就能找到要位移的位置。这个源代码下面发出来。
3:进行位移抵达位置
这里其实不难,但是最难的应该是我鼠标轨迹的问题,如果你的移动太不像人的话就会被判定为机器人,然后你的滑块会被吃掉。
在整个破解的8天历程中,写图片解析和模拟只用了2天,其余的一个星期都在各种头疼怎么模拟像人的鼠标轨迹,我甚至用pygame写了一个捕捉鼠标轨迹的脚本来用我自己真实移动的路劲来放到模拟中。
最终成功了,实现方案也是类似,认真观察人类移动的特点。自己琢磨吧,实现以后才发现,只有当你能够在phantomjs中可以实现毫秒级别的控制鼠标就很轻松过关。这方面的我不说了。
另外一个方案,就是自己搭建一个验证码的平台,然后在后台写js同时也捕捉下鼠标路径。因为像素点位移点总计也才那么一百多个,则在某像素位移点调用我之前手动移动成功的轨迹就一样可以通过,但是依旧要实现在phantom中毫秒级别的控制。成功后如下”:
2.研究资料分享
另外网络上还有一种破解思路,他并不是模拟鼠标而是进行ajax冒充:
http://blog.csdn.net/ieternite/article/details/51483491
还有同样用于模拟鼠标,只是他的图片是拼接处理,我则是截图处理。
http://www.cnblogs.com/yuananyun/p/5655019.html
然后github上也有两个我都尝试再运行起来,但是现在已经不怎么管用了,极验其实并不弱小,他们跟新的频率很高,也许过不了多久我的这就失效了。
3.图像处理算法
运行思路在前文有,在运行中成功率大约有73%。如需要测试,可以将我上文中的图一图二下载下来然后该名为jietu_1.png jietu_2.png 在同一个目录下进行测试,目前已知的是,需要PIL中的IMAGE包。如果你是window环境则一些函数会不一样。下文再发一个win的版本的。
代码语言:javascript复制#coding:utf-8
#code: python
#system: linux
#auther: luyi
#mail : **@qq.com
#github: luyishisi
#blog: https://www.urlteam.org
#date:2016.9.30
#Functional requirement: Crack verification code.
import Image
img = Image.open("jietu_1.png")
img2 = Image.open("jietu_2.png")
#切除前60列,不会出现在此
for i in xrange(0,60):
for j in xrange(img.height):
img.putpixel((i,j), (255,255,255,255))
#一列列扫描,放大差异点,相同点置白
for i in xrange(60,img.width):
for j in xrange(img.height):
r,g,b,a = img.getpixel((i,j))
r2,g2,b2,a2 = img2.getpixel((i,j))
sum = r g b
sum2 = r2 g2 b2
if abs(sum2-sum) > 15:
#print 'chayi: ',abs(sum2-sum)
abs_num = abs(sum2-sum)*5%5#我也不知道什么用,代码本天成,妙手自可得
img.putpixel((i,j), (abs_num,abs_num,abs_num,255))
else:
img.putpixel((i,j), (255,255,255,255))
#扫描首次与最后一次遇到大量深色区域的i坐标 分别赋值给i1,i2
num = 0
i1 = 0
i2 = 0
for i in xrange(img.width):
sum = 0
for j in xrange(img.height):
r,g,b,a = img.getpixel((i,j))
if(r g b)!=255 255 255:
sum = 1
if(sum > 20):
if num == 0:
num = 1
i1 = i
else :
i2 = i
#print "首次遇到大量黑色点i1: ",i1,
#print "最后遇到大量黑色点i2: ",i2,
chazhi = i2-i1
sum1 = 0
sum2 = 0
#以差值大于50做为切割点,判断哪一边是干扰点
if chazhi > 50:
for i in range(i1,chazhi/2 i1):
for j in xrange(img.height):
r,g,b,a = img.getpixel((i,j))
sum1 = sum1 r g b
for i in range(chazhi/2 i1,i2):
for j in xrange(img.height):
r,g,b,a = img.getpixel((i,j))
sum2 = sum2 r g b
if sum1>sum2:
print i2-22
else:
print i1 22
img.save('end.png')
4.模拟鼠标轨迹
这属于核心算法不透露源代码,我只说一点。一定要在phantomjs中精确到毫秒级别的控制鼠标的轨迹,你可以用下面这个pygame的代码,来捕捉自己的鼠标轨迹。
运行说明:你需要先在同目录下建立一个1000*1000的。png的文件。这个嘛。有点懒不想改代码了。环境是linux下的pygame。如果有搭建问题可以在我urlteam的博客中搜索pygame就有搭建方式。
代码语言:javascript复制#coding:utf-8
import pygame
from pygame.locals import *
from sys import exit
import time
import Image
pygame.init()
screen_size = (1000,1000)
screen = pygame.display.set_mode(screen_size, 0 ,32)
#初始化屏幕,大小1280*800,不使用特殊,32色。
font = pygame.font.SysFont("arial",16);
font_height = font.get_linesize()
event_text = []
#调用系统字体,获取行高的数值,建立一个列表用来存放事件
temp = []
num = 1000
img = Image.open("1.png")
while num:
num -= 1
event = pygame.event.wait()
if(str(event)[7] == '4'):
event_dirt = eval(str(event)[21:-2])
i = list((event_dirt['pos']))[0]
j = list((event_dirt['pos']))[1]
#img.putpixel((i,j), (255,255,255))
img.putpixel((i,j), (0,0,0))
img.putpixel((i 1,j), (0,0,0))
img.putpixel((i 1,j 1), (0,0,0))
temp.append(list((event_dirt['pos'])))
if event.type == QUIT:
exit()
screen.fill((0,0,0))
#设置背景色,0,0,0就是全黑
print temp
img.save('end.png')
最后得出的图是:
破解当你能实现鼠标轨迹的时候就已经成功了。剩余的就是用phantomjs,来一步步模拟了,。加油么么哒。
转载请附:www.urlteam.org
原创文章,转载请注明: 转载自URl-team
本文链接地址: 破解某滑动验证码
Related posts:
- 爬虫首尝试—爬取百度贴吧图片
- Scrapy-笔记二 中文处理以及保存中文数据
- Scrapy笔记三 自动多网页爬取-本wordpress博客所有文章
- Scrapy笔记零 环境搭建与五大组件架构
- Redis大批量上传数据 使用shell与python脚本
- 反爬虫之检测PhantomJS访客(翻译文)