Python Selenium破解滑块验证码最新版(GEETEST95%以上通过率)


Posted in Python onJanuary 29, 2021

一、滑块验证码简述

       有爬虫,自然就有反爬虫,就像病毒和杀毒软件一样,有攻就有防,两者彼此推进发展。而目前最流行的反爬技术验证码,为了防止爬虫自动注册,批量生成垃圾账号,几乎所有网站的注册页面都会用到验证码技术。其实验证码的英文为 CAPTCHA(Completely Automated Public Turing test to tell Computers and Humans Apart),翻译成中文就是全自动区分计算机和人类的公开图灵测试,它是一种可以区分用户是计算机还是人的测试,只要能通过 CAPTCHA 测试,该用户就可以被认为是人类。由此也可知道破解滑块验证码的关键即是让计算机更好的模拟人的行为,这也是破解的难点所在。

二、环境配置

1.安装

selenium 支持 python2.7 以及 python3.5 等主流 python 版本,其安装较为简单,有网的环境下,打开cmd输入即可自动安装:

pip install selenium

2.webdriver

selenium 安装完成后,下载所选浏览器的 webdriver,本文以 ChromeDriver为例,下载解压后切记将.exe文件放入对应Python应用程序的同级目录下,以确保将 webdriver 的路径添加至系统 PATH 变量中。同时还需将.exe文件放入Chrome应用程序的同级目录下,注意下载的ChromeDriver版本需与Chrome浏览器版本对应才可使用。ChromeDriver下载地址

3.相关库与模板

#图像处理标准库
from PIL import Image  
#web测试
from selenium import webdriver
#鼠标操作
from selenium.webdriver.common.action_chains import ActionChains
#等待时间 产生随机数 
import time,random

三、破解步骤

本文以春秋官网为例:

  • 保存滑块验证码原图到本地。
  • 利用selenium进入滑块验证码页面,截取所需页面图片。
  • 通过图片像素对比分析获取缺口位置与滑块移动距离。
  • 机器模拟人工滑动轨迹。

四、代码实现

首先通过selenium对网页元素爬取进入滑块验证码页面

#打开页面至屏幕最大尺寸
driver = webdriver.Chrome()
driver.get('https://account.ch.com/NonRegistrations-Regist')
driver.maximize_window()
#获取输入手机号码的表单
input1 = driver.find_element_by_name('phoneNumberInput')
# 输入注册号码
input1.send_keys(phoneNumber)
time.sleep(0.2)
#获取打开滑块验证码页面的元素
getcheck=driver.find_element_by_id('getDynamicPwd')
#点击进入滑块验证码页面
getcheck.click()

Python Selenium破解滑块验证码最新版(GEETEST95%以上通过率)

上周国内最大的验证码平台极验(GEETEST)进行了滑块验证码更新,向反爬虫又迈进了一步,新浪、斗鱼等使用极验验证码的各大网站页也随之更新,当然春秋也不例外,此次更新显然是针对了破解滑块验证码的关键痛点,在此之前点击获取验证码,出现滑块验证码界面之后并不会直接出现滑块,此时可对屏幕进行截图,当点击滑动圆球之后才会出现滑块与缺口,此时再次进行截图,即可根据两次截图的像素RGB值逐一遍历,找到缺口位置。但更新之后点击获取验证码,直接会出现滑块与缺口,如图1所见。问题来了,现在没有原图作为参照,怎么找到缺口位置呢???仔细一想,其实这个问题并不难,无非就是需要一张原图作为参照,经过观察发现每个网站的验证码背景图片不过区区几张,那么我们可以考虑通过人工滑动滑块,在成功拼图后出现完整原图的那一瞬间进行屏幕截图,将原图逐一截图保存至本地,再通过缺口图片与本地保存的原图进行像素RGB值匹配,原图岂不速速现出原形,缺口图圆球需滑至最右再进行截图,下文详细解释。

# 获取拖拽的圆球
slideblock = driver.find_element_by_class_name('geetest_slider_button')
# 鼠标点击圆球不松开
ActionChains(driver).click_and_hold(slideblock).perform()
# 将圆球滑至相对起点位置的最右边
ActionChains(driver).move_by_offset(xoffset=250, yoffset=0).perform()
time.sleep(0.4)
# 保存包含滑块及缺口的页面截图
driver.save_screenshot('D:\quekou.png')
# 放开圆球
ActionChains(driver).release(slideblock).perform()
#打开保存至本地的缺口页面截图
quekouimg=Image.open('d://quekou.png')
# 匹配本地对应原图
sourceimg=match_source(quekouimg)
def match_source(image):
  imagea=Image.open('d://source1.png')
  imageb=Image.open('d://source2.png')
  imagec=Image.open('d://source3.png')
  imaged=Image.open('d://source4.png')
  list=[imagea,imageb,imagec,imaged]
  #通过像素差遍历匹配本地原图
  for i in list:
    #本人电脑原图与缺口图对应滑块图片横坐标相同,纵坐标原图比缺口图大88px,可根据实际情况修改
    pixel1=image.getpixel((868,340))
    pixel2=i.getpixel((868,428))
    #pixel[0]代表R值,pixel[1]代表G值,pixel[2]代表B值
    if abs(pixel1[0]-pixel2[0])<5:
      return i
  return image

为了更快捷获取滑块移动距离,我们可以考虑将滑块先滑至最右端再进行截图,因为采用从左往右对比遍历的方式,采用这种方式能保证第一次获取到的便是缺口位置,由于滑块起点相同,此种方法可减少计算滑块大小这一步(毕竟滑块大小计算也是通过像素遍历,没必要再计算一次)。

# 获取缺口位置
visualstack=get_diff_location(sourceimg,quekouimg)
# 获取移动距离loc,827为滑块起点位置
loc=visualstack-827
# 计算滑块位移距离
def get_diff_location(image1,image2):
  #(825,1082)(335,463)为滑块图片区域,可根据实际情况修改
  for i in range(825,1082):
    for j in range(335,463):
      #遍历原图与缺口图像素值寻找缺口位置
      if is_similar(image1,image2,i,j)==False:
        return i
  return -1
# 对比RGB值得到缺口位置
def is_similar(image1,image2,x,y):
  pixel1=image1.getpixel((x, y+88))
  pixel2=image2.getpixel((x, y))
  # 截图像素也许存在误差,50作为容差范围
  if abs(pixel1[0]-pixel2[0])>=50 and abs(pixel1[1]-pixel2[1])>=50 and abs(pixel1[2]-pixel2[2])>=50:
    return False
  return True

接下来,破解滑块验证码最关键也最难的一步来了,机器模拟人工滑动轨迹,或许你可以精准滑动到缺口位置,但还是会被识别为机器被怪物吃掉拼图,本人在测试的时候也是一把辛酸泪,最后经过不断调试学习,得到一种通过率还OK的滑动轨迹算法,即采用物理加速度位移相关公式按照先快后慢的人工滑动规律进行轨迹计算,同时还采用了模拟人滑动超过了缺口位置再滑回至缺口的情况以使轨迹更契合人工滑动轨迹。由于项目时间有限,本人就没花过多时间研究了,如果想要99%通过率可以尝试机器学习,采集人工滑动轨迹进行曲线拟合的方法获取轨迹。

#滑块移动轨迹
def get_track(self,distance):
  track=[]
  current=0
  mid=distance*3/4
  t=random.randint(2,3)/10
  v=0
  while current<distance:
     if current<mid:
       a=2
     else:
       a=-3
     v0=v
     v=v0+a*t
     move=v0*t+1/2*a*t*t
     current+=move
     track.append(round(move))
  return track
# 生成拖拽移动轨迹,加3是为了模拟滑过缺口位置后返回缺口的情况
track_list=get_track(loc+3)
time.sleep(2)
ActionChains(driver).click_and_hold(slideblock).perform()
time.sleep(0.2)
# 根据轨迹拖拽圆球
for track in track_list:
  ActionChains(driver).move_by_offset(xoffset=track,yoffset=0).perform()
# 模拟人工滑动超过缺口位置返回至缺口的情况,数据来源于人工滑动轨迹,同时还加入了随机数,都是为了更贴近人工滑动轨迹
imitate=ActionChains(driver).move_by_offset(xoffset=-1, yoffset=0)
time.sleep(0.015)
imitate.perform()
time.sleep(random.randint(6,10)/10)
imitate.perform()
time.sleep(0.04)
imitate.perform()
time.sleep(0.012)
imitate.perform()
time.sleep(0.019)
imitate.perform()
time.sleep(0.033)
ActionChains(driver).move_by_offset(xoffset=1, yoffset=0).perform()
# 放开圆球
ActionChains(driver).pause(random.randint(6,14)/10).release(slideblock).perform()
time.sleep(2)
#务必记得加入quit()或close()结束进程,不断测试电脑只会卡卡西
driver.close()

至此,小白破解滑块验证码就算基本了结,整个步骤看起来挺简单的,但其中的坑大概只有实践才会知道,出BUG之后第一件事请认真检查你的代码,不要放过任何一个地方,参数、范围、返回值、取值等等,甚至可能是你最觉得没问题的地方,往往是问题所在……over

到此这篇关于Python Selenium破解滑块验证码最新版(GEETEST95%以上通过率)的文章就介绍到这了,更多相关Python Selenium破解滑块验证码内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python中列表元素连接方法join用法实例
Apr 07 Python
Python实现购物车程序
Apr 16 Python
浅析Python 3 字符串中的 STR 和 Bytes 有什么区别
Oct 14 Python
对python中大文件的导入与导出方法详解
Dec 28 Python
python tkinter实现屏保程序
Jul 30 Python
python中time库的实例使用方法
Oct 31 Python
pytorch 实现模型不同层设置不同的学习率方式
Jan 06 Python
PIL.Image.open和cv2.imread的比较与相互转换的方法
Jun 03 Python
Keras 中Leaky ReLU等高级激活函数的用法
Jul 05 Python
Python绘制组合图的示例
Sep 18 Python
Python实现自动装机功能案例分析
Oct 22 Python
Python爬取梨视频的示例
Jan 29 Python
详解pycharm的python包opencv(cv2)无代码提示问题的解决
Jan 29 #Python
如何用python开发Zeroc Ice应用
Jan 29 #Python
详解Pymongo常用查询方法总结
Jan 29 #Python
Python3使用tesserocr识别字母数字验证码的实现
Jan 29 #Python
Python爬取梨视频的示例
Jan 29 #Python
使用Python封装excel操作指南
Jan 29 #Python
用OpenCV进行年龄和性别检测的实现示例
Jan 29 #Python
You might like
php4的session功能评述(一)
2006/10/09 PHP
兼容性最强的PHP生成缩略图的函数代码(修改版)
2011/01/18 PHP
Laravel中使用FormRequest进行表单验证方法及问题汇总
2016/06/19 PHP
PHP与jquery实时显示网站在线人数实例详解
2016/12/02 PHP
php指定长度分割字符串str_split函数用法示例
2017/01/30 PHP
小议Function.apply()之二------利用Apply的参数数组化来提高 JavaScript程序性能
2006/11/30 Javascript
eval与window.eval的差别分析
2011/03/17 Javascript
javascript中声明函数的方法及调用函数的返回值
2014/07/22 Javascript
javascript Array 数组常用方法
2015/04/05 Javascript
JavaScript弹窗基础篇
2016/04/27 Javascript
Angular企业级开发——MVC之控制器详解
2017/02/20 Javascript
微信小程序 登录的简单实现
2017/04/19 Javascript
详解Vue 开发模式下跨域问题
2017/06/06 Javascript
AngularJS双向数据绑定原理之$watch、$apply和$digest的应用
2018/01/30 Javascript
React diff算法的实现示例
2018/04/20 Javascript
vue-router动态设置页面title的实例讲解
2018/08/30 Javascript
Vue+Webpack完美整合富文本编辑器TinyMce的方法
2018/11/30 Javascript
Node.js API详解之 string_decoder用法实例分析
2020/04/29 Javascript
Python单例模式实例分析
2015/01/14 Python
使用Python抓取模板之家的CSS模板
2015/03/16 Python
python中pandas.DataFrame对行与列求和及添加新行与列示例
2017/03/12 Python
深入浅析Python传值与传址
2018/07/10 Python
Python爬虫实现简单的爬取有道翻译功能示例
2018/07/13 Python
使用tensorflow实现线性回归
2018/09/08 Python
利用python GDAL库读写geotiff格式的遥感影像方法
2018/11/29 Python
Python3.8中使用f-strings调试
2019/05/22 Python
windows安装TensorFlow和Keras遇到的问题及其解决方法
2019/07/10 Python
python进阶之自定义可迭代的类
2019/08/20 Python
各大浏览器 CSS3 和 HTML5 兼容速查表 图文
2010/04/01 HTML / CSS
css3实现垂直下拉动画菜单示例
2014/04/22 HTML / CSS
沙特阿拉伯网上购物:Sayidaty Mall
2018/05/06 全球购物
手工制作的意大利礼服鞋:Ace Marks
2018/12/15 全球购物
幼儿园中班下学期评语
2014/04/18 职场文书
服务员岗位职责范本
2015/04/09 职场文书
新兵入伍决心书
2015/09/22 职场文书
python开发人人对战的五子棋小游戏
2022/05/02 Python