一、准备工作

  本次使用Selenium,浏览器为Chrome,并配置好ChromDriver

二、分析

  1.模拟点击验证按钮:可以直接使用Selenium完成。

    2.识别滑块的缺口位置:先观察图片中缺口的位置以及周围边缘,利用原图与其对比检测来识别缺口位置。

    同时获取原图与缺口图片,设定一个对比阀值,然后对两张图片进行遍历,找出相同位置像素RGB差距超过此阀值的像素点。即缺口的位置

  3.模拟拖动滑块:极验增加了机械轨迹识别与速度检测,只有完全模拟人的操作才能通过验证。运动轨迹一般先加速,然后在减速。

三,代码实现

  1.初始化

    使用魅族登陆注册页面进行测试,https://i.flyme.cn/register?。在这里先初始化一些配置

             

  

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 ECphone = '18888888888'class GeetestSpider():def __init__(self):self.url = "https://i.flyme.cn/register?"self.browser =webdriver.Chrome(executable_path=r'D:\Google\Chrome\Application\chromedriver')self.wait = WebDriverWait(self.browser, 20)self.phone = phone

  2.模拟点击  

    def get_button(self):"""获取初始验证按钮,模拟点击:return:按钮对象"""button = self.wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'geetest_radar_tip')))return button

  3.识别缺口

  获取前后两张比对图片,不一致的地方即为缺口位置。利用Selenium获取图片元素,得到位置和宽高,然后获取整个网页的截图,再将图片剪裁出来即可。  

    def get_screen_image(self):"""获取网页截图:return: 截图对象"""screen_img = self.browser.get_screenshot_as_png()screen_img = Image.open(BytesIO(screen_img))return screen_imgdef get_position(self):"""获取验证码的位置:return: 验证码位置元祖"""img = self.wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'geetest_canvas_img')))time.sleep(2)location = img.locationsize = img.sizetop, bottom, left, right = location['y'], location['y'] + size['height'], location['x'], location['x'] + size['width']return top, bottom, left, rightdef get_geetest_img(self, name='captcha.png'):"""获取验证码图片:return: 图片对象,Image对象"""top, bottom, left, right = self.get_position()print('验证码位置:', top, bottom, left, right)screen_img = self.get_screen_image()# 剪裁图片captcha = screen_img.crop((left, top, right, bottom))     captcha.save(name)return captchadef get_slider(self):"""获取滑块:return:滑块对象"""slider = self.wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'geetest_slider_button')))return slider

  获取滑块slider之后,调用click()方法即可触发点击,缺口图片就好呈现出来。再调用get_geetest_img()方法将获取第二章图片。

  将获取到的两张图片分别赋值给img1,img2。进行图片对比,遍历图片的每个坐标点,获取两张图片对应像素点的RGB数据。如果二者的RGB数据差在一定的范围内,则代表两个像素相同,继续进行下一个点的对比。如果差距超过一定范围,则代表像素点不相同,即缺口的位置。

    def equal_rgb(self, img1, img2, x, y):"""判断两个像素点是否相同:param img1: 图片1:param img2: 图片2:param x: 位置x:param y: 位置y:return: 是否相同"""# 获取两张图片的像素点pixel1 = img1.load()[x, y]pixel2 = img2.load()[x, y]threshold = 60if abs(pixel1[0] - pixel2[0]) < threshold and abs(pixel1[1] - pixel2[1]) < threshold and abs(pixel1[2] - pixel2[2]) < threshold:return Trueelse:return Falsedef get_gap(self, img1, img2):"""获取偏移量:param img1:不带缺口的图片:param img2: 带缺口的图片:return: 偏移量"""left = 60for i in range(left, img1.size[0]):for j in range(img1.size[1]):if not self.equal_rgb(img1,img2,i,j):left = ireturn leftreturn left

  4.模拟拖动滑块

  为了模拟人的操作,滑块的拖动速度不应该是匀速,也不应该是保持在某一速度上下抖动。滑块的速度变化应该是一开始在加速,接近缺口就会减速,想象一下我们手动拖动滑块的情况。

  滑块的加速度用a表示,当前速度用v表示,初始速度用v0表示,移动距离用x表示,运动时间t表示,满足以下关系:

  x = v0 * t + a * t * t / 2

  v = v0 + a * t  

    def get_track(self, d):"""根据偏移量获取运动轨迹:param d: 偏移量:return: 运动轨迹,每次移动距离"""# 运动轨迹track = []# 当前位移current = 0# 开始减速的偏移量,设位移达到偏移量的2/3时开始减速deviation = d * 2 / 3#  间隔时间t = 0.2# 初始速度v = 0while current < d:if current < deviation:# 加速阶段a = 2else:# 减速阶段a = -2# 初始速度v0 = v# 当前速度v = v0 + a * t# 位移move = v0 * t + a * t * t / 2# 当前位移current += move# 添加到轨迹,保留整数
            track.append(round(move))return trackdef move_slider(self, slider, track):"""按照轨迹移动滑块至缺口:param slider:滑块:param track: 轨迹:return:"""# 鼠标按住滑块
        ActionChains(self.browser).click_and_hold(slider).perform()for i in track:# 遍历轨迹元素,每次移动对应位移ActionChains(self.browser).move_by_offset(xoffset=i, yoffset=0).perform()time.sleep(0.5)# 移动完成后,松开鼠标ActionChains(self.browser).release().perform()

  验证成功:

    

 

5.完整代码

# _*_ coding=utf-8 _*_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# 初始化
class GeetestSpider():def __init__(self):self.url = "https://i.flyme.cn/register"self.browser = webdriver.Chrome(executable_path=r'D:\Google\Chrome\Application\chromedriver')self.wait = WebDriverWait(self.browser, 20)def get_button(self):"""获取初始验证按钮,模拟点击:return:按钮对象"""button = self.wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'geetest_radar_tip_content')))return buttondef get_screen_image(self):"""获取网页截图:return: 截图对象"""screen_img = self.browser.get_screenshot_as_png()screen_img = Image.open(BytesIO(screen_img))return screen_imgdef get_position(self):"""获取验证码的位置:return: 验证码位置元祖"""img = self.wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'geetest_canvas_img')))time.sleep(2)location = img.locationsize = img.sizetop, bottom, left, right = location['y'], location['y'] + size['height'], location['x'], location['x'] + size['width']return top, bottom, left, rightdef get_geetest_img(self, name='captcha.png'):"""获取验证码图片:return: 图片对象,Image对象"""top, bottom, left, right = self.get_position()print('验证码位置:', top, bottom, left, right)screen_img = self.get_screen_image()# 剪裁图片captcha = screen_img.crop((left, top, right, bottom))captcha.save(name)return captchadef get_slider(self):"""获取滑块:return:滑块对象"""slider = self.wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'geetest_slider_button')))return sliderdef equal_rgb(self, img1, img2, x, y):"""判断两个像素点是否相同:param img1: 图片1:param img2: 图片2:param x: 位置x:param y: 位置y:return: 是否相同"""# 获取两张图片的像素点pixel1 = img1.load()[x, y]pixel2 = img2.load()[x, y]threshold = 60if abs(pixel1[0] - pixel2[0]) < threshold and abs(pixel1[1] - pixel2[1]) < threshold and abs(pixel1[2] - pixel2[2]) < threshold:return Trueelse:return Falsedef get_gap(self, img1, img2):"""获取偏移量:param img1:不带缺口的图片:param img2: 带缺口的图片:return: 偏移量"""# 直接从滑块的右侧开始遍历left = 60for i in range(left, img1.size[0]):for j in range(img1.size[1]):if not self.equal_rgb(img1, img2, i, j):left = ireturn leftreturn leftdef get_track(self, d):"""根据偏移量获取运动轨迹:param d: 偏移量:return: 运动轨迹,每次移动距离"""# 运动轨迹track = []# 当前位移current = 0# 开始减速的偏移量,设位移达到偏移量的2/3时开始减速deviation = d * 2 / 3#  间隔时间t = 0.2# 初始速度v = 0while current < d:if current < deviation:# 加速阶段a = 2else:# 减速阶段a = -2# 初始速度v0 = v# 当前速度v = v0 + a * t# 位移move = v0 * t + a * t * t / 2# 当前位移current += move# 添加到轨迹,保留整数
            track.append(round(move))return trackdef move_slider(self, slider, track):"""按照轨迹移动滑块至缺口:param slider:滑块:param track: 轨迹:return:"""# 鼠标按住滑块
        ActionChains(self.browser).click_and_hold(slider).perform()for i in track:# 遍历轨迹元素,每次移动对应位移ActionChains(self.browser).move_by_offset(xoffset=i, yoffset=0).perform()time.sleep(0.5)# 移动完成后,松开鼠标
        ActionChains(self.browser).release().perform()def crack(self):"""模拟验证的各种操作:return:None"""# 打开网站,输入注册手机号
        self.browser.get(self.url)self.wait.until(EC.presence_of_element_located((By.ID, 'phone')))# 点击验证button = self.get_button()button.click()# 获取验证码图片img1 = self.get_geetest_img('captcha1.png')# 获取滑块slider = self.get_slider()slider.click()# 获取带缺口的图片img2 = self.get_geetest_img('captcha2.png')# 获取缺口位置gap = self.get_gap(img1, img2)print("缺口位置:", gap)# 减去缺口位移gap -= 6# 获取轨迹track = self.get_track(gap)print("轨迹:", track)# 拖动滑块
        self.move_slider(slider, track)success = self.wait.until(EC.text_to_be_present_in_element((By.ID, 'geetest_success_radar_tip_content'), '验证成功'))# 失败重试if not success:self.crack()if __name__ == '__main__':crack = GeetestSpider()crack.crack()

View Code

  

转载于:https://www.cnblogs.com/zivli/p/11013043.html

爬虫—GEETEST滑动验证码识别相关推荐

  1. 网络爬虫笔记—滑动验证码识别

    网络爬虫笔记-滑动验证码识别 一.什么是滑动验证码 点击之前 点击之后 像这种通过滑动图片,补全缺口的方式,就是滑动验证码. 二.识别思路 1)使用selenium库操作谷歌浏览器,打开目标网站:关于 ...

  2. 用Python爬虫破解滑动验证码

    我们可以借用opencv来解决这个问题,主要步骤: opencv 是什么? OpenCV(Open Source Computer Vision Library)是开放源代码计算机视觉库,主要算法涉及 ...

  3. 网络爬虫笔记—图形验证码识别

    网络爬虫笔记-图形验证码识别 <兄弟们,本文章开启了关注后阅读.大家如不想关注,可直接微信搜索"宏蜘蛛"或文章标题,查看文章.> 1.什么是图形验证码 像知网注册界面的 ...

  4. Python爬虫解决极验(geetest)滑动验证码

    csdn_okcheng 滑动验证码的识别介绍 实现步骤: ① 初始化 ② 模拟登录填写,点开滑块验证 ③ 获取并储存有无缺口的两张图片 ④ 获取缺口位置 ⑤ 获取移动轨迹 ⑥ 按照轨迹拖动,完全验证 ...

  5. Python爬虫过程中验证码识别的三种解决方案

    在Python爬虫过程中,有些网站需要验证码通过后方可进入网页,目的很简单,就是区分是人阅读访问还是机器爬虫.验证码问题看似简单,想做到准确率很高,也是一件不容易的事情.为了更好学习爬虫,后续推文中将 ...

  6. 网络爬虫中的验证码识别

    网络爬虫遇到的验证码 在写网络,爬虫时,遇到很多网站存在验证码的情形,有其是比较烦的是,爬取数据的每一页都有验证码,如果只有登陆时,存在验证码,这个很好解决,只需将验证码获取后手动输入就行. 但对于每 ...

  7. 爬虫代理和验证码识别

    代理操作 - 目的:为解决ip被封的情况 概念汇总:- 什么是代理?- 代理服务器- 代理和爬虫之间的关联是什么?- 网络爬虫是需要短时间内发送高频的请求,为了保障ip不被封掉,使用代理更换请求对应的 ...

  8. Python爬虫之网站验证码识别(三)

    视频链接:Python爬虫7天速成(2020全新合集)无私分享 Python: 章节p29-p31 文章目录 前言 一.云打码平台使用流程 操作流程 二.代码编写⭐ 2.1 使用超级鹰云平台 2.2 ...

  9. 滑动验证码识别----解决天眼查自动登录问题

    滑动验证码验证如下图所示: 解决这个问题的思路: 1.获取无缺口和有缺口的两张图片,即:下图所示: 2.对比两张图片的像素点,像素点差值超过一定值即可视为缺口点(这里对比像素点时最好将开始的那一部分截 ...

最新文章

  1. “面试不败计划“:hibernate和mybatis比较
  2. matlab之unwrap函数
  3. 十条技巧 更聪明地使用Google搜索
  4. linux rpm 没有返回,容易忘记的linux命令之rpm
  5. iOS 开发之获取时间到年底可能会踩到的坑
  6. python tkinter listbox_Python3 tkinter基础 Listbox for+insert 将list中元素导入listbox中
  7. PID控制器开发笔记之十三:单神经元PID控制器的实现
  8. 【征稿+竞赛】WACV 2021 第一届无人车视觉学术研讨会
  9. ECCV 2020 论文大盘点-场景解析篇
  10. 7-3 括号匹配 (15 分)
  11. Golang 网络爬虫框架gocolly/colly
  12. SQL Server从入门到精通(三)
  13. vb连接mysql的方法_VB几种连接数据库的方法
  14. [乱七八糟]《进化论——人类科学史上最大的谎言》
  15. 中兴2016校招软件在线笔试题
  16. jquery的插件有哪些
  17. 计算机网络说明文,《Wi-Fi》初中说明文阅读题及答案
  18. 2小时开发《点球射门游戏》,动画演示思路(上),代码已开源
  19. QT基础学习笔记 Demo01
  20. 百倍加速:Python量化策略的算法性能提升指南

热门文章

  1. stm32USMART调试组件——HAL库
  2. h5页面调用用户手机打电话功能以及复制内容到剪切板
  3. 字符串压缩与解压 题解
  4. Vim编辑模式怎么退出
  5. vue全局变量的配置
  6. 一个基于角色的权限控制系统
  7. 社交电商再次升温, 无忧猴正掀起第三次零售革命
  8. 《教育的目的》笔记——如何让学生通过树木看见森林
  9. qq for ubuntu 10.04总是掉线
  10. ALV字段‘‘QUAN‘小数位全为零不显示小数位,不全为零显示小数位