摘要

爬虫最大的敌人之一是什么?没错,验证码!Geetest作为提供验证码服务的行家,市场占有率还是蛮高的。遇到Geetest提供的滑动验证码怎么破?授人予鱼不如授人予渔,接下来就为大家呈现本教程的精彩内容。

 

爬虫进阶教程:极验(GEETEST)验证码破解教程

一、前言

爬虫最大的敌人之一是什么?没错,验证码!Geetest作为提供验证码服务的行家,市场占有率还是蛮高的。遇到Geetest提供的滑动验证码怎么破?

一种方法是分析它的js加密方法,通过大量抓包分析找到它的返回参数,直接自动生成需要的参数即可,这种方法工程量大一些,并且官方js脚本一升级,就得重新分析,耗时耗力。

今天为大家介绍的一种方法是,通过Selenium模拟用户滑动解锁。这个方法的优势在于简单,方便更新。但是它的缺点也很明显,速度慢,并且不能制作成api接口的形式。

授人予鱼不如授人予渔,接下来就为大家呈现本教程的精彩内容。不过,在阅读本篇文章之前,请确保你已经掌握网络爬虫基础,如果不具备爬虫基础,请到我的CSDN专栏学习。然后,再来阅读本文,我的专栏地址:点我查看

二、先睹为快

爬虫进阶教程:极验(GEETEST)验证码破解教程

左侧显示的为自动识别过程,右边是一些打印信息。

三、实战分析

我们以国家企业信用信息公式系统为例,这是一个企业信息查询的网站,在每次查询都需要进行一次验证码识别。它所使用的就是GEETEST验证码,它的URL:点我查看

这个网站是这个样子的:

爬虫进阶教程:极验(GEETEST)验证码破解教程

1、过程分析

要想把大象装冰箱,总共分几步?

  • 把冰箱门打开
  • 把大象赛冰箱里
  • 把冰箱门关上

那么,现在思考一个问题,通过Selenium模拟用户滑动解锁,总共分几步?请停在这里,思考五分钟,再继续阅读!

我们先公布一个粗率的答案:

  • 使用Selenium打开页面。
  • 匹配到输入框,输入要查询的信息,并点击查询按钮。
  • 读取验证码图片,并做缺口识别。
  • 根据缺口位置,计算滑动距离。
  • 根据滑动距离,拖拽滑块到需要匹配的位置。

其实,将每个步骤拆分开来一点一点实现并不难,接下来进入正文。

2、实战开始

第一步:使用Selenium打开网页,并输入信息,点击查询按钮。

这部分内容很简单,Selenium基础性的东西我不再讲解,如有不懂,请看我专栏的Selenium相关内容。

编写代码如下:

# -*-coding:utf-8 -*-
EC
WebDriverWait
By
webdriver
:
:
;
)
)
keyword
:
        打开浏览器,并输入查询内容
)
)
)
)
)
:
# 打开浏览器
)
:
)
)
)
 
 

爬虫进阶教程:极验(GEETEST)验证码破解教程

第二步:保存验证码图片

我们审查元素找打图片的地址,审查结果如下:

爬虫进阶教程:极验(GEETEST)验证码破解教程

可以看到,图片是很多图片合成的,也就是说你只保存所有地址的图片是不行的。它是通过background-position的方法进行合成的。每一个图片是乱的,这个怎么搞?很简单,抓取这些图片的链接,然后根据链接的图片,再合成这张没有缺口的图片,获取缺口图的方法也是如此,都是自己合成。

编写代码如下:

 
# -*-coding:utf-8 -*-
random
image
BytesIO
Image
webdriver
By
ActionChains
WebDriverWait
EC
urllib
BeautifulSoup
urlretrieve
:
:
;
)
)
keyword
6
:
)
)
:
        获取网页截图
        :return: 截图对象
)
)
screenshot
:
        获取验证码位置
        :return: 验证码位置元组
)
)
location
size
]
)
:
        获取验证码图片
        :return: 图片对象
)
)
)
)
)
captcha
:
        获取验证码图片
        :return: 图片的location信息
]
]
:
)
)
)
)
)
]
]
:
}
)
)
)
:
}
)
)
)
)
)
)
)
fullbg_location_list
:
        根据位置对图片进行合并还原
        :filename:图片
        :location_list:图片位置
)
)
]
]
:
:
)
:
)
)
0
:
)
]
0
:
)
]
)
new_im
:
)
)
)
)
)
:
        获取滑块
        :return: 滑块对象
:
:
)
break
:
)
slider
:
        获取缺口偏移量
        :param img1: 不带缺口图片
        :param img2: 带缺口图片
        :return:
43
:
:
:
i
left
left    
    
:
        判断两个像素是否相同
        :param image1: 图片1
        :param image2: 图片2
        :param x: 位置x
        :param y: 位置y
        :return: 像素是否相同
# 取两个图片的像素点
]
]
60
:
True
:
False
:
        根据偏移量获取移动轨迹
        :param distance: 偏移量
        :return: 移动轨迹
# 移动轨迹
]
# 当前位移
0
# 减速阈值
5
# 计算间隔
0.2
# 初速度
0
        
:
:
# 加速度为正2
2
    
# 加速度为负3
3
# 初速度v0
v
# 当前速度v = v0 + at
t
# 移动距离x = v0t + 1/2 * a * t^2
t
# 当前位移
move
# 加入轨迹
)
track
:
        拖动滑块到缺口处
        :param slider: 滑块
        :param track: 轨迹
        :return:
)
:
)
)
)
)
)
:
# 打开浏览器
)
        
        
# 保存的图片名字
'bg.jpg'
'fullbg.jpg'
# 获取图片
)
# 根据位置对图片进行合并还原
)
)
        
# 点按呼出缺口
)
        
# 获取缺口位置
)
)
)
)
)
)
:
)
)
)
)
 

运行效果如下:

爬虫进阶教程:极验(GEETEST)验证码破解教程

可以看到,运行之后,我们已经顺利生成了两张图片,一个是缺口图,另一个是非缺口图。

第三步:计算缺口距离

根据缺口图和非缺口图,通过比对图像的像素点的大小区别,找到缺口位置。

编写代码如下:

# -*-coding:utf-8 -*-
EC
WebDriverWait
By
urlretrieve
webdriver
BeautifulSoup
image
re
 
:
:
'http://bj.gsxt.gov.cn/sydq/loginSydqAction!sydq.dhtml'
)
)
keyword
 
:
        打开浏览器,并输入查询内容
)
)
)
)
)
 
:
        获取验证码图片
        :return: 图片的location信息
]
]
:
)
)
)
)
)
]
]
:
}
)
)
)
:
}
)
)
)
 
)
)
)
)
fullbg_location_list
 
:
        根据位置对图片进行合并还原
        :filename:图片
        :location_list:图片位置
)
)
]
]
 
:
:
)
:
)
 
)
 
0
:
)
]
 
0
:
)
]
 
)
 
new_im
 
:
        根据位置对图片进行合并还原
        :filename:图片
        :location_list:图片位置
)
)
]
]
 
:
:
)
:
)
 
)
 
0
:
)
]
 
0
:
)
]
 
)
 
new_im
 
:
        获取缺口偏移量
        :param img1: 不带缺口图片
        :param img2: 带缺口图片
        :return:
43
:
:
:
i
left
left  
 
:
# 打开浏览器
)
 
# 保存的图片名字
'bg.jpg'
'fullbg.jpg'
 
# 获取图片
)
 
# 根据位置对图片进行合并还原
)
)
 
# 获取缺口位置
)
)
 
:
)
)
)

运行结果如下:

爬虫进阶教程:极验(GEETEST)验证码破解教程

这样我们就计算除了缺口位置,接下来就是根据缺口位置,滑动滑块到相应位置。

第四步:计算滑动轨迹

我们可以使用瞬间移动,直接在1s内移动到目标位置,结果就是”被吃了“。

爬虫进阶教程:极验(GEETEST)验证码破解教程

匀速直线运动,匀速直线运动大法好!果不其然,还是”被吃了“,继续尝试。

爬虫进阶教程:极验(GEETEST)验证码破解教程

模仿抖抖病患者运动,颤颤巍巍,如履薄冰,估计geetest服务器认为是我外婆在操作吧。

爬虫进阶教程:极验(GEETEST)验证码破解教程

虽然这个方法偶尔会成功,但成功率极低。最好的方法是什么呢?

模拟人的运动!你想一下,人在滑动滑块的初期是不是速度快,但是当要接近缺口位置的时候,会减速,因为我得对准缺口位置啊!这怎么实现呢?使用我们初中学过的物理知识:

当前速度公式为:

v = v0 + a * t

其中,v是当前速度,v0是初始速度,a是加速度,t是时间。我们刚开始的让加速大,当过了中间位置,降低加速度。使用这个移动过程,移动滑块到缺口位置。

编写代码如下:

 
# -*-coding:utf-8 -*-
EC
WebDriverWait
By
urlretrieve
webdriver
BeautifulSoup
image
re
 
:
:
'http://bj.gsxt.gov.cn/sydq/loginSydqAction!sydq.dhtml'
)
)
keyword
6
 
:
        打开浏览器,并输入查询内容
)
)
)
)
)
 
:
        获取验证码图片
        :return: 图片的location信息
]
]
:
)
)
)
)
)
]
]
:
}
)
)
)
:
}
)
)
)
 
)
)
)
)
fullbg_location_list
 
:
        根据位置对图片进行合并还原
        :filename:图片
        :location_list:图片位置
)
)
]
]
 
:
:
)
:
)
 
)
 
0
:
)
]
 
0
:
)
]
 
)
 
new_im
 
:
        根据位置对图片进行合并还原
        :filename:图片
        :location_list:图片位置
)
)
]
]
 
:
:
)
:
)
 
)
 
0
:
)
]
 
0
:
)
]
 
)
 
new_im
 
:
        判断两个像素是否相同
        :param image1: 图片1
        :param image2: 图片2
        :param x: 位置x
        :param y: 位置y
        :return: 像素是否相同
# 取两个图片的像素点
]
]
60
:
True
:
False
 
:
        获取缺口偏移量
        :param img1: 不带缺口图片
        :param img2: 带缺口图片
        :return:
43
:
:
:
i
left
left  
 
:
        根据偏移量获取移动轨迹
        :param distance: 偏移量
        :return: 移动轨迹
# 移动轨迹
]
# 当前位移
0
# 减速阈值
5
# 计算间隔
0.2
# 初速度
0
 
:
:
# 加速度为正2
2
  
# 加速度为负3
3
# 初速度v0
v
# 当前速度v = v0 + at
t
# 移动距离x = v0t + 1/2 * a * t^2
t
# 当前位移
move
# 加入轨迹
)
track
 
:
# 打开浏览器
)
 
# 保存的图片名字
'bg.jpg'
'fullbg.jpg'
 
# 获取图片
)
 
# 根据位置对图片进行合并还原
)
)
 
# 获取缺口位置
)
)
 
)
)
)
 
 
:
)
)
)
运行效果如下:

爬虫进阶教程:极验(GEETEST)验证码破解教程

第五步:移动滑块

根据返回的每次滑动的距离,我们移动滑块至缺口位置。

编写代码如下:

 
# -*-coding:utf-8 -*-
EC
WebDriverWait
By
urlretrieve
webdriver
BeautifulSoup
image
re
 
:
:
'http://bj.gsxt.gov.cn/sydq/loginSydqAction!sydq.dhtml'
)
)
keyword
6
 
:
        打开浏览器,并输入查询内容
)
)
)
)
)
 
:
        获取验证码图片
        :return: 图片的location信息
]
]
:
)
)
)
)
)
]
]
:
}
)
)
)
:
}
)
)
)
 
)
)
)
)
fullbg_location_list
 
:
        根据位置对图片进行合并还原
        :filename:图片
        :location_list:图片位置
)
)
]
]
 
:
:
)
:
)
 
)
 
0
:
)
]
 
0
:
)
]
 
)
 
new_im
 
:
        根据位置对图片进行合并还原
        :filename:图片
        :location_list:图片位置
)
)
]
]
 
:
:
)
:
)
 
)
 
0
:
)
]
 
0
:
)
]
 
)
 
new_im
 
:
        判断两个像素是否相同
        :param image1: 图片1
        :param image2: 图片2
        :param x: 位置x
        :param y: 位置y
        :return: 像素是否相同
# 取两个图片的像素点
]
]
60
:
True
:
False
 
:
        获取缺口偏移量
        :param img1: 不带缺口图片
        :param img2: 带缺口图片
        :return:
43
:
:
:
i
left
left  
 
:
        根据偏移量获取移动轨迹
        :param distance: 偏移量
        :return: 移动轨迹
# 移动轨迹
]
# 当前位移
0
# 减速阈值
5
# 计算间隔
0.2
# 初速度
0
 
:
:
# 加速度为正2
2
  
# 加速度为负3
3
# 初速度v0
v
# 当前速度v = v0 + at
t
# 移动距离x = v0t + 1/2 * a * t^2
t
# 当前位移
move
# 加入轨迹
)
track
 
:
        获取滑块
        :return: 滑块对象
:
:
)
break
:
)
slider
 
:
        拖动滑块到缺口处
        :param slider: 滑块
        :param track: 轨迹
        :return:
)
:
)
)
)
)
)
 
:
# 打开浏览器
)
 
# 保存的图片名字
'bg.jpg'
'fullbg.jpg'
 
# 获取图片
)
 
# 根据位置对图片进行合并还原
)
)
 
# 获取缺口位置
)
)
 
)
)
)
 
# 点按呼出缺口
)
# 拖动滑块到缺口处
)
 
:
)
)
)
)
 

运行上述代码,即实现滑动验证码破解,再看下那个nice的瞬间吧。

爬虫进阶教程:极验(GEETEST)验证码破解教程

五、总结

  • 本文抛去了很多具体的实现过程,省略了每行代码的讲解,因为我感觉,既然是进阶教程,那些初级知识就没必要再细讲,学我的初级课程的朋友,应该已经具备了自己分析的能力。
  • 本文的破解方法仅用于学习交流,请勿用于任何非法用途。
  • 本文出现的所有代码和,均可在我的github上下载,欢迎Follow、Star:https://github.com/Jack-Cherish/python-spider
  • 如有问题欢迎留言讨论!

 如果破解极验验证码困难 可以有一个挺好的解决方案 http://jiyandoc.c2567.com/

 

相关文章:

  • 2022-02-10
  • 2021-12-20
  • 2022-12-23
  • 2021-06-27
  • 2023-02-20
  • 2022-12-23
  • 2022-12-23
  • 2021-08-17
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-06-04
  • 2021-09-24
  • 2021-11-23
相关资源
相似解决方案