欢迎来到Introzo百科
Introzo百科
当前位置:网站首页 > 技术 > python验证码识别(二)杰贤滑动验证码识别

python验证码识别(二)杰贤滑动验证码识别

日期:2023-10-01 09:17

-->

目录
  • 1:捷县滑动验证码介绍
  • 2:识别滑动验证码的思路
  • 三:验证码识别
    • 1。极测试验证码官网:https://www.introzo.com/login/
    • 2.初始化配置
    • 3。模拟点击
    • 4。找出差距
    • 5。模拟拖动
    • 6:所有代码

1:介县滑动验证码介绍

   近年来,出现了一些新型的验证码。虽然旧的验证码对人类并不友好,但识别此类验证码的难度却增加了好几个级别。因此,需要采取其他手段来应对。

  确定所需的 python 库:selenium 和 ChromeDriver 驱动程序。不同的浏览器有不同的驱动库需要下载。

验证码获取网址:http://www.introzo.com/

解仙滑动验证码已经到了3.0版本。图形验证码识别难度较大。原理就是将图片拖到间隙处,然后组合图片进行验证。将生成三个加密参数并通过表单提交给后端。然后后端将进行身份验证。

极语验证码还添加了机器学习方法来识别是否是恶意程序。具有防模拟、防伪造、防暴力手段。只需要0.4秒,保护资源不被滥用和窃取。

我们的程序只要不被恶意爬取并且遵守爬虫协议一般是没问题的。永远不要给服务器造成负担。

2:捷先滑动验证码识别思路

  这里我们可以通过模拟浏览器动作来完成验证,利用Selenium完全模拟人的行为来完成验证。

主要分为三个步骤

(1) 模拟点击验证按钮

(2) 识别滑动间隙

的位置 (3) 模拟拖动滑块

步骤(1)说起来比较容易。步骤(2)更关键的是识别接口的位置。需要进行图像处理来查看界面的位置,并将其与原始图像进行比较,以识别间隙的位置。同时获取两张图片,设置一个对比度阈值,然后遍历两张图片,找出同一像素的RGB差值超过这个阈值的像素。那么像素位置就是间隙的位置。

步骤(3)是困难的。由于人体运动轨迹先加速后减速,匀速运动、随机运动等方法无法通过验证。这个过程一定要模拟好。

三:验证码识别

1。极测验证码官网:https://www.introzo.com/login/

官网图片为:

2.初始化配置

#注册的用户名和密码
电子邮件 = ''
密码='' 类 CrackGeetest():
def __init__(self):
self.url = 'https://www.introzo.com/login'
self.browser = www.introzo.com()
self.wait = WebDriverWait(self.browser, 20)
www.introzo.com = 电子邮件
self.password = 密码

3。模拟点击

  识别验证码第一步是模拟点击初始验证按钮,通过显式等待获取。

def get_geetest_button(self):
”“”
获取初始验证按钮
返回值:按钮对象
”“”
按钮 = self.wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'geetest_radar_tip')))
返回按钮

  您可以在调用位置模拟点击:

#点击验证按钮
按钮 = self.get_geetest_button()
按钮.click()

4。找出差距

  接下来要确定间隙的位置,首先获取两张图片并进行比较。不同的位置就是间隙。

获得无间隙的图像。使用selenium选择图像元素来获取整个网页的屏幕截图,然后进行裁剪。代码如下:

def get_screenshot(自我):
”“”
获取网页截图
:return: 截图对象
”“”
屏幕截图 = self.browser.get_screenshot_as_png()
截图 = www.introzo.com(BytesIO(截图))
返回截图 def get_position(self):
”“”
获取验证码位置
:return: 验证码位置元组
”“”
img = self.wait.until(EC.presence_of_element_ located((By.CLASS_NAME, 'geetest_canvas_img')))
时间.睡眠(2)
位置 = img.位置
尺寸 = img.尺寸
上、下、左、右 = 位置['y']、位置['y'] + 尺寸['高度']、位置['x']、位置['x'] + 尺寸[
‘宽度’]
返回(上、下、左、右) def get_geetest_image(self, name='captcha.png'):
”“”
获取验证码图片
:return: 图片对象
”“”
上、下、左、右 = self.get_position()
print('验证码位置',上、下、左、右)
截图 = self.get_screenshot()
验证码 = 截图.crop((左、上、右、下))
验证码.save(姓名)
返回验证码

   接下来,你需要获取第二张图片,也就是有间隙的图片。只需单击下面的滑块即可显示间隙。代码如下:

def get_slider(self):
”“”
获取滑块
:return: 滑块对象
”“”
slider = self.wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'geetest_slider_button')))
返回滑块

  使用click()触发点击,如下:

#点击即可调出间隙
滑块 = self.get_slider()
www.introzo.com()

   下一步就是通过图片对比来获取间隙,并通过遍历图片上的每个坐标点,获取两张图片的像素对应的RGB数据。如果在一定范围内,则说明两个像素相同,继续与下一个像素进行比较。如果差异超过一定范围,则说明像素不同,当前位置就是间隙位置。通过设置阈值threshold来进行判断。代码如下:

def is_pixel_equal(self, image1, image2, x, y):
”“”
判断两个像素是否相同
:param image1: 图片1
:param image2: 图片2
:param x: 位置 x
:param y: 位置 y
:return: 像素是否相同
”“”
# 获取两张图片的像素
Pixel1 = image1.load()[x, y]
Pixel2 = image2.load()[x, y]
阈值 = 60
如果abs(像素1[0] - 像素2[0]) < 阈值且abs(像素1[1] - 像素2[1]) < 阈值且abs(
像素1[2] - 像素2[2]) < 阈值:
返回 True
其他:
返回错误 def get_gap(self, image1, image2):
”“”
获取凹口偏移
:param image1: 无缺口的图片
:param image2: 缺口图像
:返回:
”“”
左 = 60
对于范围内的 i(左,image1.size[0]):
对于 j 在范围内(image1.size[1]):
如果不是 www.introzo.com_pixel_equal(image1, image2, i, j):
左 = i
向左返回
向左返回

5。模拟拖动

  模拟阻力并不复杂,但里面的细节更多。使用相关功能将滑块拖动到相应位置。但如果匀速拖动的话,肯定会被识别为程序而不是人为操作。由于人类无法以完全恒定的速度拖动,因此会识别出这是机器操作,导致验证码失败。

通过不同的检测方法,我们发现通过使前滑块匀加速运动、后滑块匀减速运动即可完成验证。

这里加速度用a表示,当前速度用v表示,初速度用vo表示,位移用x表示,时间用t表示。

代码如下:

def get_track(自身,距离):
”“”
根据偏移量获取运动轨迹
:参数距离:偏移量
:return: 运动轨迹
”“”
#移动轨道
曲目 = []
# 当前位移
电流 = 0
# 减速度阈值
中 = 距离 * 4 / 5
# 计算间隔
t = 0.2
#初速度
v = 0 当当前<距离:
如果当前 < 中值:
# 加速度为正 2
a = 2
其他:
# 加速度为负值 3
a = -3
#初速度v0
v0 = v
# 当前速度 v = v0 + at
v = v0 + a * t
#移动距离x = v0t + 1/2 * a * t^2
移动 = v0 * t + 1 / 2 * a * t * t
# 当前位移
当前+=移动
#添加曲目
track.append(轮(移动))
返回轨道 def move_to_gap(自身,滑块,轨道):
”“”
将滑块拖动到间隙
:参数滑块:滑块
:参数轨道:轨道
:返回:
”“”
ActionChains(self.browser).click_and_hold(slider).perform()
对于轨道中的 x:
ActionChains(self.browser).move_by_offset(xoffset=x, yoffset=0).perform()
时间.睡眠(0.5)
ActionChains(self.browser).release().perform()

6:所有代码

导​​入时间
从 io 导入 BytesIO
从 PIL 导入图像
从 selenium 导入 webdriver
从 selenium.webdriver 导入 ActionChains
来自 www.introzo.com 导入 By
从 selenium.webdriver.support.ui 导入 WebDriverWait
从 selenium.webdriver.support 导入预期条件作为 EC 邮箱='support@www.introzo.com'
密码=''
边框 = 6
初始化左 = 60 # 注册的用户名和密码
电子邮件 = ''
密码='' 类 CrackGeetest():
def __init__(self):
self.url = 'https://www.introzo.com/login'
self.browser = www.introzo.com()
self.wait = WebDriverWait(self.browser, 20)
www.introzo.com = 电子邮件
self.密码 = 密码 def __del__(自身):
self.浏览器.close() def get_geetest_button(self):
”“”
获取初始验证按钮
返回值:按钮对象
”“”
按钮 = self.wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'geetest_radar_tip')))
返回按钮 def get_screenshot(self):
”“”
获取网页截图
:return: 截图对象
”“”
截图 = self.browser.get_screenshot_as_png()
截图 = www.introzo.com(BytesIO(截图))
返回截图 def get_position(self):
”“”
获取验证码位置
:return: 验证码位置元组
”“”
img = self.wait.until(EC.presence_of_element_ located((By.CLASS_NAME, 'geetest_canvas_img')))
时间.睡眠(2)
位置 = img.位置
尺寸 = img.尺寸
上、下、左、右 = 位置['y']、位置['y'] + 尺寸['高度']、位置['x']、位置['x'] + 尺寸[
‘宽度’]
返回(上、下、左、右) def get_geetest_image(self, name='captcha.png'):
”“”
获取验证码图片
:return: 图片对象
”“”
上、下、左、右 = self.get_position()
print('验证码位置',上、下、左、右)
截图 = self.get_screenshot()
验证码 = 截图.crop((左、上、右、下))
验证码.save(姓名)
返回验证码 def get_slider(self):
”“”
获取滑块
:return: 滑块对象
”“”
slider = self.wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'geetest_slider_button')))
返回滑块 def 打开(自己):
”“”
打开网页并输入您的用户名和密码
:返回: 无
”“”
self.browser.get(self.url)
电子邮件 = self.wait.until(EC.presence_of_element_ located((www.introzo.com, '电子邮件')))
密码 = self.wait.until(EC.presence_of_element_ located((www.introzo.com, '密码')))
email.send_keys(www.introzo.com)
密码.send_keys(self.密码) def is_pixel_equal(self, image1, image2, x, y):
”“”
判断两个像素是否相同
:param image1: 图片1
:param image2: 图片2
:param x: 位置 x
:param y: 位置 y
:return: 像素是否相同
”“”
# 获取两张图片的像素
Pixel1 = image1.load()[x, y]
Pixel2 = image2.load()[x, y]
阈值 = 60
如果abs(像素1[0] - 像素2[0]) < 阈值且abs(像素1[1] - 像素2[1]) < 阈值且abs(
像素1[2] - 像素2[2]) < 阈值:
返回 True
其他:
返回错误 def get_gap(self, image1, image2):
”“”
获取凹口偏移
:param image1: 无缺口的图片
:param image2: 缺口图像
:返回:
”“”
左 = 60
对于范围内的 i(左,image1.size[0]):
对于 j 在范围内(image1.size[1]):
如果不是 www.introzo.com_pixel_equal(image1, image2, i, j):
左 = i
向左返回
向左返回 def get_track(自身, 距离):
”“”
根据偏移量获取运动轨迹
:参数距离:偏移量
:return: 运动轨迹
”“”
#移动轨道
曲目 = []
# 当前位移
电流 = 0
# 减速度阈值
中 = 距离 * 4 / 5
# 计算间隔
t = 0.2
#初速度
v = 0 当当前<距离:
如果当前 < 中值:
# 加速度为正 2
a = 2
其他:
# 加速度为负值 3
a = -3
#初速度v0
v0 = v
# 当前速度 v = v0 + at
v = v0 + a * t
#移动距离x = v0t + 1/2 * a * t^2
移动 = v0 * t + 1 / 2 * a * t * t
# 当前位移
当前+=移动
#添加曲目
track.append(轮(移动))
返回轨道 def move_to_gap(自身,滑块,轨道):
”“”
将滑块拖动到间隙
:参数滑块:滑块
:参数轨道:轨道
:返回:
”“”
ActionChains(self.browser).click_and_hold(slider).perform()
对于轨道中的 x:
ActionChains(self.browser).move_by_offset(xoffset=x, yoffset=0).perform()
时间.睡眠(0.5)
ActionChains(self.browser).release().perform() def 登录(自己):
”“”
登录
:返回: 无
”“”
提交 = self.wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'login-btn')))
提交.click()
时间.睡眠(10)
print('登录成功') def破解(自身):
# 输入用户名和密码
www.introzo.com()
# 点击验证按钮
按钮 = self.get_geetest_button()
按钮.单击() #获取验证码图片
image1 = self.get_geetest_image('验证码1.png')
# 点击即可调出间隙
滑块 = self.get_slider()
www.introzo.com()
# 获取缺口验证码图片
image2 = self.get_geetest_image('验证码2.png')
# 获取间隙位置
间隙 = self.get_gap(image1, image2)
print('间隙位置', 间隙)
# 减去缺口位移
间隙-=边界
#获取运动轨迹
track = self.get_track(gap)
print('滑动轨道', track)
# 拖动滑块
self.move_to_gap(滑块,轨道) 成功 = self.wait.until(
EC.text_to_be_present_in_element((By.CLASS_NAME, 'geetest_success_radar_tip_content'), '验证成功'))
打印(成功) #失败后再试
如果不成功:
self.crack()
其他:
自我登录() if __name__ == '__main__':
破解 = CrackGeetest()
裂纹.裂纹()

此方法适用于不同的解县滑动验证码。关键在于识别思路,如何识别间隙位置,如何生成运动轨迹等,如果以后遇到类似的验证码,可以通过这种方式识别。

-->