百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术资源 > 正文

python验证码识别,极验滑动验证码识别

off999 2024-10-23 12:52 43 浏览 0 评论

一:极验滑动验证码简介

??近些年来出现了一些新型验证码,不想旧的验证码对人类不友好,但是这种验证码对于代码来说识别难度上升了几个等级。因此需要其他的手段进行处理。
??识别需要的python库:selenium和ChromeDriver驱动,不同浏览器的要下载的驱动库不同。
?
??极验滑动验证码已经到了3.0版本,相关于图形验证码识别难度更大,原理是拖动图片到缺口处,然后拼合图像进行验证,会生成三个加密参数,通过表单提交到后台,后台再进行验证。
??极验验证码还增加了机器学习的方法来识别是否是恶意程序进行识别,有防模拟,防伪造,防暴力的方式, 只需0.4秒,并且保护资源不被滥用和盗取。
??我们的程序一般只要不是恶意进行爬取的,并遵守爬虫协议,就可以。千万不要给服务器造成负担。

二:极验滑动验证码识别思路

??这里我们可以采用模拟浏览器动作的方式完成验证,用Selenium来完全模拟人的行为完成验证。
??主要分为三步
??(1)模拟点击验证按钮
??(2)识别滑动缺口的位置
??(3)模拟拖动滑块
??第(1)步还比较好说,第(2)步操作识别接口的位置比较关键,需要用到图像处理看到接口的位置,并和原图对比检测的方法来识别缺口的位置。同时获取两张图片,设定一个对比阈值,然后遍历两张图片,找出相同像素RGB差距超过此阈值的像素点,那么像素点位置就是缺口的位置。
??第(3)步较难,由于人的移动轨迹是先加速后减速,匀速移动和随机移动等方法都不能通过验证,要模拟好这个过程。

三:极验验证码识别

1.极验验证码官网

官网图片为:

2.初始化配置

# 注册的用户名和密码
email = ''
password = ''

class CrackGeetest():
 def __init__(self):
 self.url = 'https://account.geetest.com/login'
 self.browser = webdriver.Chrome()
 self.wait = WebDriverWait(self.browser, 20)
 self.email = email
 self.password = password

3.模拟点击

??识别验证码第一步就是模拟点击初始的验证按钮,用显式等待的方法进行获取。

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

??在调用位置即可模拟点击:

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

4.识别缺口

??接下来识别缺口的位置,首先获取两张图片,进行对比,不一样的位置就是缺口。
??获取不带缺口的图片。用selenium选取图片元素得到整个网页的截图然后裁剪即可,代码如下:

def get_screenshot(self):
 """
 获取网页截图
 :return: 截图对象
 """
 screenshot = self.browser.get_screenshot_as_png()
 screenshot = Image.open(BytesIO(screenshot))
 return screenshot

 def get_position(self):
 """
 获取验证码位置
 :return: 验证码位置元组
 """
 img = self.wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'geetest_canvas_img')))
 time.sleep(2)
 location = img.location
 size = img.size
 top, bottom, left, right = location['y'], location['y'] + size['height'], location['x'], location['x'] + size[
 'width']
 return (top, bottom, left, right)

 def get_geetest_image(self, name='captcha.png'):
 """
 获取验证码图片
 :return: 图片对象
 """
 top, bottom, left, right = self.get_position()
 print('验证码位置', top, bottom, left, right)
 screenshot = self.get_screenshot()
 captcha = screenshot.crop((left, top, right, bottom))
 captcha.save(name)
 return captcha

??接下来需要获取第二张图片,就是带有缺口的图片,只需要点击下面的滑块就能出现缺口,代码如下:

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

??用click()即可触发点击,如下:

# 点按呼出缺口
slider = self.get_slider()
slider.click()

??接下来就是通过对比图片获取缺口,通过遍历图片上的每个坐标点,获取两张图片对应像素点的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]
 threshold = 60
 if abs(pixel1[0] - pixel2[0]) < threshold and abs(pixel1[1] - pixel2[1]) < threshold and abs(
 pixel1[2] - pixel2[2]) < threshold:
 return True
 else:
 return False

 def get_gap(self, image1, image2):
 """
 获取缺口偏移量
 :param image1: 不带缺口图片
 :param image2: 带缺口图片
 :return:
 """
 left = 60
 for i in range(left, image1.size[0]):
 for j in range(image1.size[1]):
 if not self.is_pixel_equal(image1, image2, i, j):
 left = i
 return left
 return left

5.模拟拖动

??模拟拖动并不复杂,但是里面的细节比较多。用相关的函数将滑块拖动到对应的位置即可。但是要是匀速拖动,会必然识别出是程序,非人类操作,因为人类无法做到完全匀速拖动,会识别出是机器操作,使得验证码失败。
??通过不同的方法检测,我们发现把前段滑块做匀加速运动,后段滑块做匀减速运动,即可完成验证。
??这里加速度用a来表示,当前速度用v表示,初速度用vo表示,位移用x表示,时间用t表示。
??代码如下:

def get_track(self, distance):
 """
 根据偏移量获取移动轨迹
 :param distance: 偏移量
 :return: 移动轨迹
 """
 # 移动轨迹
 track = []
 # 当前位移
 current = 0
 # 减速阈值
 mid = distance * 4 / 5
 # 计算间隔
 t = 0.2
 # 初速度
 v = 0
 
 while current < distance:
 if current < mid:
 # 加速度为正2
 a = 2
 else:
 # 加速度为负3
 a = -3
 # 初速度v0
 v0 = v
 # 当前速度v = v0 + at
 v = v0 + a * t
 # 移动距离x = v0t + 1/2 * a * t^2
 move = v0 * t + 1 / 2 * a * t * t
 # 当前位移
 current += move
 # 加入轨迹
 track.append(round(move))
 return track
 
 def move_to_gap(self, slider, track):
 """
 拖动滑块到缺口处
 :param slider: 滑块
 :param track: 轨迹
 :return:
 """
 ActionChains(self.browser).click_and_hold(slider).perform()
 for x in track:
 ActionChains(self.browser).move_by_offset(xoffset=x, yoffset=0).perform()
 time.sleep(0.5)
 ActionChains(self.browser).release().perform()

6:全部代码

import time
from io import BytesIO
from PIL import Image
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

EMAIL = 'cqc@cuiqingcai.com'
PASSWORD = ''
BORDER = 6
INIT_LEFT = 60

# 注册的用户名和密码
email = ''
password = ''


class CrackGeetest():
 def __init__(self):
 self.url = 'https://account.geetest.com/login'
 self.browser = webdriver.Chrome()
 self.wait = WebDriverWait(self.browser, 20)
 self.email = email
 self.password = password
 
 def __del__(self):
 self.browser.close()
 
 def get_geetest_button(self):
 """
 获取初始验证按钮
 返回值:按钮对象
 """
 button = self.wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'geetest_radar_tip')))
 return button
 
 def get_screenshot(self):
 """
 获取网页截图
 :return: 截图对象
 """
 screenshot = self.browser.get_screenshot_as_png()
 screenshot = Image.open(BytesIO(screenshot))
 return screenshot

 def get_position(self):
 """
 获取验证码位置
 :return: 验证码位置元组
 """
 img = self.wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'geetest_canvas_img')))
 time.sleep(2)
 location = img.location
 size = img.size
 top, bottom, left, right = location['y'], location['y'] + size['height'], location['x'], location['x'] + size[
 'width']
 return (top, bottom, left, right)
 
 def get_geetest_image(self, name='captcha.png'):
 """
 获取验证码图片
 :return: 图片对象
 """
 top, bottom, left, right = self.get_position()
 print('验证码位置', top, bottom, left, right)
 screenshot = self.get_screenshot()
 captcha = screenshot.crop((left, top, right, bottom))
 captcha.save(name)
 return captcha

 def get_slider(self):
 """
 获取滑块
 :return: 滑块对象
 """
 slider = self.wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'geetest_slider_button')))
 return slider
 
 def open(self):
 """
 打开网页输入用户名密码
 :return: None
 """
 self.browser.get(self.url)
 email = self.wait.until(EC.presence_of_element_located((By.ID, 'email')))
 password = self.wait.until(EC.presence_of_element_located((By.ID, 'password')))
 email.send_keys(self.email)
 password.send_keys(self.password)
 
 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]
 threshold = 60
 if abs(pixel1[0] - pixel2[0]) < threshold and abs(pixel1[1] - pixel2[1]) < threshold and abs(
 pixel1[2] - pixel2[2]) < threshold:
 return True
 else:
 return False

 def get_gap(self, image1, image2):
 """
 获取缺口偏移量
 :param image1: 不带缺口图片
 :param image2: 带缺口图片
 :return:
 """
 left = 60
 for i in range(left, image1.size[0]):
 for j in range(image1.size[1]):
 if not self.is_pixel_equal(image1, image2, i, j):
 left = i
 return left
 return left
 
 def get_track(self, distance):
 """
 根据偏移量获取移动轨迹
 :param distance: 偏移量
 :return: 移动轨迹
 """
 # 移动轨迹
 track = []
 # 当前位移
 current = 0
 # 减速阈值
 mid = distance * 4 / 5
 # 计算间隔
 t = 0.2
 # 初速度
 v = 0
 
 while current < distance:
 if current < mid:
 # 加速度为正2
 a = 2
 else:
 # 加速度为负3
 a = -3
 # 初速度v0
 v0 = v
 # 当前速度v = v0 + at
 v = v0 + a * t
 # 移动距离x = v0t + 1/2 * a * t^2
 move = v0 * t + 1 / 2 * a * t * t
 # 当前位移
 current += move
 # 加入轨迹
 track.append(round(move))
 return track
 
 def move_to_gap(self, slider, track):
 """
 拖动滑块到缺口处
 :param slider: 滑块
 :param track: 轨迹
 :return:
 """
 ActionChains(self.browser).click_and_hold(slider).perform()
 for x in track:
 ActionChains(self.browser).move_by_offset(xoffset=x, yoffset=0).perform()
 time.sleep(0.5)
 ActionChains(self.browser).release().perform()
 
 def login(self):
 """
 登录
 :return: None
 """
 submit = self.wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'login-btn')))
 submit.click()
 time.sleep(10)
 print('登录成功')
 
 def crack(self):
 # 输入用户名密码
 self.open()
 # 点击验证按钮
 button = self.get_geetest_button()
 button.click()

 # 获取验证码图片
 image1 = self.get_geetest_image('captcha1.png')
 # 点按呼出缺口
 slider = self.get_slider()
 slider.click()
 # 获取带缺口的验证码图片
 image2 = self.get_geetest_image('captcha2.png')
 # 获取缺口位置
 gap = self.get_gap(image1, image2)
 print('缺口位置', gap)
 # 减去缺口位移
 gap -= BORDER
 # 获取移动轨迹
 track = self.get_track(gap)
 print('滑动轨迹', track)
 # 拖动滑块
 self.move_to_gap(slider, track)
 
 success = self.wait.until(
 EC.text_to_be_present_in_element((By.CLASS_NAME, 'geetest_success_radar_tip_content'), '验证成功'))
 print(success)
 
 # 失败后重试
 if not success:
 self.crack()
 else:
 self.login()


if __name__ == '__main__':
 crack = CrackGeetest()
 crack.crack()

这种方法对于不同的极验滑动验证码来说都适用,关键在于识别的思路,如何识别缺口位置,如何生成运动轨迹等。之后遇到类似的验证码,都可以这样进行识别。

最后,小编想说:我是一名python开发工程师,整理了一套最新的python系统学习教程,想要这些资

料的可以关注私信小编“01”即可,希望能对你有所帮助。

相关推荐

安全教育登录入口平台(安全教育登录入口平台官网)

122交通安全教育怎么登录:122交通网的注册方法是首先登录网址http://www.122.cn/,接着打开网页后,点击右上角的“个人登录”;其次进入邮箱注册,然后进入到注册页面,输入相关信息即可完...

大鱼吃小鱼经典版(大鱼吃小鱼经典版(经典版)官方版)

大鱼吃小鱼小鱼吃虾是于谦跟郭麒麟的《我的棒儿呢?》郭德纲说于思洋郭麒麟作诗的相声,最后郭麒麟做了一首,师傅躺在师母身上大鱼吃小鱼小鱼吃虾虾吃水水落石出师傅压师娘师娘压床床压地地动山摇。...

谷歌地球下载高清卫星地图(谷歌地球地图下载器)
  • 谷歌地球下载高清卫星地图(谷歌地球地图下载器)
  • 谷歌地球下载高清卫星地图(谷歌地球地图下载器)
  • 谷歌地球下载高清卫星地图(谷歌地球地图下载器)
  • 谷歌地球下载高清卫星地图(谷歌地球地图下载器)
哪个软件可以免费pdf转ppt(免费的pdf转ppt软件哪个好)
哪个软件可以免费pdf转ppt(免费的pdf转ppt软件哪个好)

要想将ppt免费转换为pdf的话,我们建议大家可以下一个那个wps,如果你是会员的话,可以注册为会员,这样的话,在wps里面的话,就可以免费将ppt呢转换为pdfpdf之后呢,我们就可以直接使用,不需要去直接不需要去另外保存,为什么格式转...

2026-02-04 09:03 off999

电信宽带测速官网入口(电信宽带测速官网入口app)

这个网站看看http://www.swok.cn/pcindex.jsp1.登录中国电信网上营业厅,宽带光纤,贴心服务,宽带测速2.下载第三方软件,如360等。进行在线测速进行宽带测速时,尽...

植物大战僵尸95版手机下载(植物大战僵尸95 版下载)

1可以在应用商店或者游戏平台上下载植物大战僵尸95版手机游戏。2下载教程:打开应用商店或者游戏平台,搜索“植物大战僵尸95版”,找到游戏后点击下载按钮,等待下载完成即可安装并开始游戏。3注意:确...

免费下载ppt成品的网站(ppt成品免费下载的网站有哪些)

1、Chuangkit(chuangkit.com)直达地址:chuangkit.com2、Woodo幻灯片(woodo.cn)直达链接:woodo.cn3、OfficePlus(officeplu...

2025世界杯赛程表(2025世界杯在哪个国家)

2022年卡塔尔世界杯赛程公布,全部比赛在卡塔尔境内8座球场举行,2022年,决赛阶段球队全部确定。揭幕战于当地时间11月20日19时进行,由东道主卡塔尔对阵厄瓜多尔,决赛于当地时间12月18日...

下载搜狐视频电视剧(搜狐电视剧下载安装)

搜狐视频APP下载好的视频想要导出到手机相册里方法如下1、打开手机搜狐视频软件,进入搜狐视频后我们点击右上角的“查找”,找到自已喜欢的视频。2、在“浏览器页面搜索”窗口中,输入要下载的视频的名称,然后...

pubg免费下载入口(pubg下载入口官方正版)
  • pubg免费下载入口(pubg下载入口官方正版)
  • pubg免费下载入口(pubg下载入口官方正版)
  • pubg免费下载入口(pubg下载入口官方正版)
  • pubg免费下载入口(pubg下载入口官方正版)
永久免费听歌网站(丫丫音乐网)

可以到《我爱音乐网》《好听音乐网》《一听音乐网》《YYMP3音乐网》还可以到《九天音乐网》永久免费听歌软件有酷狗音乐和天猫精灵,以前要跳舞经常要下载舞曲,我从QQ上找不到舞曲下载就从酷狗音乐上找,大多...

音乐格式转换mp3软件(音乐格式转换器免费版)

有两种方法:方法一在手机上操作:1、进入手机中的文件管理。2、在其中选择“音乐”,将显示出手机中的全部音乐。3、点击“全选”,选中所有音乐文件。4、点击屏幕右下方的省略号图标,在弹出菜单中选择“...

电子书txt下载(免费的最全的小说阅读器)

1.Z-library里面收录了近千万本电子书籍,需求量大。2.苦瓜书盘没有广告,不需要账号注册,使用起来非常简单,直接搜索预览下载即可。3.鸠摩搜书整体风格简洁清晰,书籍资源丰富。4.亚马逊图书书籍...

最好免费观看高清电影(播放免费的最好看的电影)

在目前的网上选择中,IMDb(互联网电影数据库)被认为是最全的电影网站之一。这个网站提供了各种类型的电影和电视节目的海量信息,包括剧情介绍、演员表、评价、评论等。其还提供了有关电影制作背后的详细信息,...

孤单枪手2简体中文版(孤单枪手2简体中文版官方下载)

要将《孤胆枪手2》游戏的征兵秘籍切换为中文,您可以按照以下步骤进行操作:首先,打开游戏设置选项,通常可以在游戏主菜单或游戏内部找到。然后,寻找语言选项或界面选项,点击进入。在语言选项中,选择中文作为游...

取消回复欢迎 发表评论: