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随机生成带特殊字符的密码
Mar 02 Python
Python实现屏幕截图的代码及函数详解
Oct 01 Python
python3使用pandas获取股票数据的方法
Dec 22 Python
详解python--模拟轮盘抽奖游戏
Apr 12 Python
python爬虫神器Pyppeteer入门及使用
Jul 13 Python
Python pandas用法最全整理
Aug 04 Python
python带参数打包exe及调用方式
Dec 21 Python
python中的itertools的使用详解
Jan 13 Python
python3 deque 双向队列创建与使用方法分析
Mar 24 Python
解决reload(sys)后print失效的问题
Apr 25 Python
Django ORM 查询表中某列字段值的方法
Apr 30 Python
基于selenium及python实现下拉选项定位select
Jul 22 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
php 仿Comsenz安装效果代码打包提供下载
2010/05/09 PHP
开启PHP的伪静态模式
2015/12/31 PHP
php自定义函数br2nl实现将html中br换行符转换为文本输入中换行符的方法【与函数nl2br功能相反】
2017/02/17 PHP
php检测mysql表是否存在的方法小结
2017/07/20 PHP
javascript 表单规则集合对象
2009/07/21 Javascript
获取URL地址中的文件名和参数的javascript代码
2009/09/02 Javascript
JavaScript 事件记录使用说明
2009/10/20 Javascript
JS trim去空格的最佳实践
2011/10/30 Javascript
JQuery入门—编写一个简单的JQuery应用案例
2013/01/03 Javascript
js的参数有长度限制吗?发现不能超过2083个字符
2014/04/20 Javascript
基于NodeJS的前后端分离的思考与实践(三)轻量级的接口配置建模框架
2014/09/26 NodeJs
JavaScript运行机制之事件循环(Event Loop)详解
2014/10/10 Javascript
小议JavaScript中Generator和Iterator的使用
2015/07/29 Javascript
jquery简单倒计时实现方法
2015/12/18 Javascript
jQuery设置聚焦并使光标位置在文字最后的实现方法
2016/08/02 Javascript
图片懒加载插件实例分享(含解析)
2017/01/09 Javascript
Bootstrap Scrollspy源码学习
2017/03/02 Javascript
JS代码优化的8点建议
2020/02/04 Javascript
[01:13:59]LGD vs Mineski Supermajor 胜者组 BO3 第三场 6.5
2018/06/06 DOTA
Python调用百度根据经纬度查询地址的示例代码
2019/07/07 Python
python中常用的数据结构介绍
2021/01/12 Python
DeinDesign德国:设计自己的手机壳
2019/12/14 全球购物
家居设计专业个人自荐信范文
2013/11/26 职场文书
养殖行业的创业计划书
2014/01/05 职场文书
广告设计应届生求职信
2014/03/01 职场文书
职业生涯规划书范文
2014/03/10 职场文书
手术室护士长竞聘书
2014/03/31 职场文书
关于读书的演讲稿1000字
2014/08/27 职场文书
活动总结格式
2014/08/30 职场文书
四风个人对照检查材料思想汇报(办公室通用版)
2014/10/07 职场文书
无子女夫妻离婚协议书(4篇)
2014/10/20 职场文书
小学六一儿童节活动总结
2015/05/05 职场文书
恰同学少年观后感
2015/06/08 职场文书
班主任班级管理心得体会
2016/01/07 职场文书
SQL Server代理:理解SQL代理错误日志处理方法
2021/06/30 SQL Server
win10清理dns缓存
2022/04/19 数码科技