普通滑动验证

http://admin.emaotai.cn/login.aspx为例这类验证码只需要我们将滑块拖动指定位置,处理起来比较简单。拖动之前需要先将滚动条滚动到指定元素位置。

import time
from selenium import webdriver
from selenium.webdriver import ActionChains # 新建selenium浏览器对象,后面是geckodriver.exe下载后本地路径
browser = webdriver.Firefox() # 网站登陆页面
url = 'http://admin.emaotai.cn/login.aspx' # 浏览器访问登录页面
browser.get(url) browser.maximize_window() browser.implicitly_wait(5) draggable = browser.find_element_by_id('nc_1_n1z') # 滚动指定元素位置
browser.execute_script("arguments[0].scrollIntoView();", draggable) time.sleep(2) ActionChains(browser).click_and_hold(draggable).perform() # 拖动
ActionChains(browser).move_by_offset(xoffset=247, yoffset=0).perform() ActionChains(browser).release().perform()

拼图滑动验证

我们以欧模网很多网站使用的都是类似的方式。因为验证码及拼图都有明显明亮的边界,图片辨识度比较高。所以我们尝试先用cv2的边缘检测识别出边界,然后进行模糊匹配,匹配出拼图在验证码图片的位置。

边缘检测

pip install opencv-python

cv2模块提供了多种边缘检测算子,包括Sobel、Scharr、Laplacian、prewitt、Canny或Marr—Hildreth等,每种算子得出的结果不同。这里我们用Canny算子,测试了很多算子,这种效果最好。

Canny

我们通过一个程序调整一下canny算子的阈值,使得输出图片只包含拼图轮廓。

import cv2

lowThreshold = 0
maxThreshold = 100 # 最小阈值范围 0 ~ 500
# 最大阈值范围 100 ~ 1000 def canny_low_threshold(intial):
blur = cv2.GaussianBlur(img, (3, 3), 0)
canny = cv2.Canny(blur, intial, maxThreshold)
cv2.imshow('canny', canny) def canny_max_threshold(intial):
blur = cv2.GaussianBlur(img, (3, 3), 0)
canny = cv2.Canny(blur, lowThreshold, intial)
cv2.imshow('canny', canny) # 参数0以灰度方式读取
img = cv2.imread('vcode.png', 0) cv2.namedWindow('canny', cv2.WINDOW_NORMAL | cv2.WINDOW_KEEPRATIO)
cv2.createTrackbar('Min threshold', 'canny', lowThreshold, max_lowThreshold, canny_low_threshold)
cv2.createTrackbar('Max threshold', 'canny', maxThreshold, max_maxThreshold, canny_max_threshold)
canny_low_threshold(0) # esc键退出
if cv2.waitKey(0) == 27:
cv2.destroyAllWindows()

测试了若干个图片发现最小阈值100、最大阈值500输出结果比较理想。

拼图匹配

我们用cv2的matchTemplate方法进行模糊匹配,匹配方法用CV_TM_CCOEFF_NORMED归一化相关系数匹配。

几种方法算法详见
【1】 平方差匹配 method=CV_TM_SQDIFF square dirrerence(error)
这类方法利用平方差来进行匹配,最好匹配为0.匹配越差,匹配值越大.
【2】标准平方差匹配 method=CV_TM_SQDIFF_NORMED standard square dirrerence(error)
【3】 相关匹配 method=CV_TM_CCORR
这类方法采用模板和图像间的乘法操作,所以较大的数表示匹配程度较高,0标识最坏的匹配效果.
【4】 标准相关匹配 method=CV_TM_CCORR_NORMED
【5】 相关匹配 method=CV_TM_CCOEFF
这类方法将模版对其均值的相对值与图像对其均值的相关值进行匹配,1表示完美匹配,
-1表示糟糕的匹配,0表示没有任何相关性(随机序列).
【6】标准相关匹配 method=CV_TM_CCOEFF_NORMED

canndy_test.py:

import cv2
import numpy as np def matchImg(imgPath1,imgPath2): imgs = [] # 原始图像,用于展示
sou_img1 = cv2.imread(imgPath1)
sou_img2 = cv2.imread(imgPath2) # 原始图像,灰度
# 最小阈值100,最大阈值500
img1 = cv2.imread(imgPath1, 0)
blur1 = cv2.GaussianBlur(img1, (3, 3), 0)
canny1 = cv2.Canny(blur1, 100, 500)
cv2.imwrite('temp1.png', canny1) img2 = cv2.imread(imgPath2, 0)
blur2 = cv2.GaussianBlur(img2, (3, 3), 0)
canny2 = cv2.Canny(blur2, 100, 500)
cv2.imwrite('temp2.png', canny2) target = cv2.imread('temp1.png')
template = cv2.imread('temp2.png') # 调整显示大小
target_temp = cv2.resize(sou_img1, (350, 200))
target_temp = cv2.copyMakeBorder(target_temp, 5, 5, 5, 5, cv2.BORDER_CONSTANT, value=[255, 255, 255]) template_temp = cv2.resize(sou_img2, (200, 200))
template_temp = cv2.copyMakeBorder(template_temp, 5, 5, 5, 5, cv2.BORDER_CONSTANT, value=[255, 255, 255]) imgs.append(target_temp)
imgs.append(template_temp) theight, twidth = template.shape[:2] # 匹配拼图
result = cv2.matchTemplate(target, template, cv2.TM_CCOEFF_NORMED) # 归一化
cv2.normalize( result, result, 0, 1, cv2.NORM_MINMAX, -1 ) min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
  
  #如果不需要看后面的效果,只要返回位置,把下面的注释去掉
  #return max_loc[0] # 匹配后结果画圈
cv2.rectangle(target,max_loc,(max_loc[0]+twidth,max_loc[1]+theight),(0,0,255),2) target_temp_n = cv2.resize(target, (350, 200))
target_temp_n = cv2.copyMakeBorder(target_temp_n, 5, 5, 5, 5, cv2.BORDER_CONSTANT, value=[255, 255, 255]) imgs.append(target_temp_n) imstack = np.hstack(imgs) cv2.imshow('stack'+str(max_loc), imstack) cv2.waitKey(0)
cv2.destroyAllWindows() matchImg('vcode_data/out_'+str(1)+'.png','vcode_data/in_'+str(1)+'.png')

我们测试几组数据,发现准确率拿来玩玩尚可。max_loc就是匹配出来的位置信息,我们只需要按照位置进行拖动即可。

完整程序

完整流程1.实例化浏览器 2.点击登陆,弹出滑动验证框 3.分别新建标签页打开背景图及拼图 4.全屏截图后按照尺寸裁剪 5.模糊匹配两张图片,获取匹配结果位置信息 6.将位置信息转为页面上的位移距离 7.拖动滑块到指定位置

import time
import cv2
import canndy_test
from selenium import webdriver
from selenium.webdriver import ActionChains # 新建selenium浏览器对象,后面是geckodriver.exe下载后本地路径
browser = webdriver.Firefox() # 网站登陆页面
url = 'https://www.om.cn/login' # 浏览器访问登录页面
browser.get(url) handle = browser.current_window_handle # 等待3s用于加载脚本文件
browser.implicitly_wait(3) # 点击登陆按钮,弹出滑动验证码
btn = browser.find_element_by_class_name('login_btn1')
btn.click() # 获取iframe元素,切到iframe
frame = browser.find_element_by_id('tcaptcha_iframe')
browser.switch_to.frame(frame) time.sleep(1) # 获取背景图src
targetUrl = browser.find_element_by_id('slideBg').get_attribute('src') # 获取拼图src
tempUrl = browser.find_element_by_id('slideBlock').get_attribute('src') # 新建标签页
browser.execute_script("window.open('');")
# 切换到新标签页
browser.switch_to.window(browser.window_handles[1]) # 访问背景图src
browser.get(targetUrl)
time.sleep(3)
# 截图
browser.save_screenshot('temp_target.png') w = 680
h = 390 img = cv2.imread('temp_target.png') size = img.shape top = int((size[0] - h) / 2)
height = int(h + ((size[0] - h) / 2))
left = int((size[1] - w) / 2)
width = int(w + ((size[1] - w) / 2)) cropped = img[top:height, left:width] # 裁剪尺寸
cv2.imwrite('temp_target_crop.png', cropped) # 新建标签页
browser.execute_script("window.open('');") browser.switch_to.window(browser.window_handles[2]) browser.get(tempUrl)
time.sleep(3) browser.save_screenshot('temp_temp.png') w = 136
h = 136 img = cv2.imread('temp_temp.png') size = img.shape top = int((size[0] - h) / 2)
height = int(h + ((size[0] - h) / 2))
left = int((size[1] - w) / 2)
width = int(w + ((size[1] - w) / 2)) cropped = img[top:height, left:width] cv2.imwrite('temp_temp_crop.png', cropped) browser.switch_to.window(handle) # 模糊匹配两张图片
move = canndy_test.matchImg('temp_target_crop.png', 'temp_temp_crop.png') # 计算出拖动距离
distance = int(move / 2 - 27.5) + 2 draggable = browser.find_element_by_id('tcaptcha_drag_thumb') ActionChains(browser).click_and_hold(draggable).perform() # 拖动
ActionChains(browser).move_by_offset(xoffset=distance, yoffset=0).perform() ActionChains(browser).release().perform() time.sleep(10)

tips:可能会存在第一次不成功的情况,虽然拖动到了指定位置但是提示网络有问题、拼图丢失。可以进行循环迭代直到拼成功为止。通过判断iframe中id为slideBg的元素是否存在,如果成功了则不存在,失败了会刷新拼图让你重新拖动。

if(isEleExist(browser,'slideBg')):
# retry
else:
return def isEleExist(browser,id):
try:
browser.find_element_by_id(id)
return True
except:
return False

python模拟网站登陆-滑动验证码的更多相关文章

  1. python urllib2 模拟网站登陆

    python urllib2 模拟网站登陆 1. 可用浏览器先登陆,然后查看网页源码,分析登录表单 2. 使用python urllib2,cookielib 模拟网页登录 import urllib ...

  2. Python 破解极验滑动验证码

    Python 破解极验滑动验证码 测试开发社区  1周前 阅读目录 极验滑动验证码 实现 位移移动需要的基础知识 对比两张图片,找出缺口 获得图片 按照位移移动 详细代码 回到顶部 极验滑动验证码 以 ...

  3. C# 模拟网站登陆

    实现此功能首先需要借助一些抓包工具,对相应的网站登陆过程进行分析,此过程根据网站的不同,可能复杂,也可能很简单.常用的抓包工具FF下FireBug和IE下的HttpWatch.这两个工具很强大,以此工 ...

  4. 模拟Post登陆带验证码的网站

    前言: 作者在一个项目需求 模拟用户登陆,获取该用户的订单记录. 该系统需要用户名,密码,验证码 (验证码为正楷的数字4位),于是参考网络一些文章,并进行了很多测试,总结步骤如下: 步骤1 : 通过h ...

  5. Python——破解极验滑动验证码

    极验滑动验证码 以上图片是最典型的要属于极验滑动认证了,极验官网:http://www.geetest.com/. 现在极验验证码已经更新到了 3.0 版本,截至 2017 年 7 月全球已有十六万家 ...

  6. Python模拟微博登陆,亲测有效

    今天想做一个微博爬个人页面的工具,满足一些不可告人的秘密.那么首先就要做那件必做之事!模拟登陆-- 代码是参考了:https://www.douban.com/note/201767245/ 我对代码 ...

  7. python模拟---注册登陆查看个人信息

    需求:1.模拟注册: 2.模拟登陆: 3.模拟登陆成功显示登陆成功的用户账号: 一.注册 代码如下: def regetist(): ''' :param username: 注册的账号 :param ...

  8. 使用python模拟cookie登陆wooyun

    import urllib2 class SimpleCookieHandler(urllib2.BaseHandler): def http_request(self, req): simple_c ...

  9. python模拟艺龙网登录带验证码输入

    1.使用urllib与urllib2包 2.使用cookielib自动管理cookie 3.360浏览器F12抓信息 登录请求地址和验证码地址都拿到了如图 # -*- coding: utf-8 -* ...

随机推荐

  1. Error creating bean with name 'org.springframework.aop.aspectj.AspectJPointc

    问题 出现报错: Error creating bean with name 'org.springframework.aop.aspectj.AspectJPointc 原因 缺失两个库文件: as ...

  2. E. Physical Education Lessons 动态开辟线段树区间更新

    E. Physical Education Lessons time limit per test 1 second memory limit per test 256 megabytes input ...

  3. 10个典型的JavaScript面试题

    问题1:作用域 考虑如下代码:   JavaScript   1 2 3 4 5 6 7 (function() {   var a = b = 5;   })();   console.log(b) ...

  4. Java中异常分类和Throw和Throws的区别

    Java中异常分类和Throw和Throws的区别 1.异常分类 Throwable是Java中所有错误和异常的超类.它的下一级是Error和Exception 1.1 Error(错误) Error ...

  5. MySQL复制表结构以及复制表等等

    mysql中用命令行复制表结构的方法主要有一下几种: 1.只复制表结构到新表 1 CREATE TABLE 新表 SELECT * FROM 旧表 WHERE 1=2; 或 1 CREATE TABL ...

  6. mantis2.22.1中添加管理员密码修改框

    1.修改文件 mantis/manage_user_edit_page.php 找到<!-- Email -->位置,将以下代码粘贴到下面即可:<tr <?php echo h ...

  7. Order by 优化

    写在前面 文章涉及到的 customer 表来源于案例库 sakila,下载地址为 http://downloads.mysql.com/docs/sakila-db.zip MySQL 排序方式 通 ...

  8. 读Pyqt4教程,带你入门Pyqt4 _006

    窗口组件是应用程序的基本构建块.PyQt4编程工具包拥有范围广泛的各种窗口组件.按钮.选择框.滑块.列表框等等,程序员工作所需要的一切.在教程的这部分中,我们将介绍一些有用的窗口组件. QCheckB ...

  9. 跟着阿里学JavaDay01——Java编程环境搭建

    一.下载并完成JDK的安装 我们要学习Java就需要下载JDK.因为JDK是Java的开发工具. JDK的获取可以通过官方网站下载:JDK下载地址(这里我们下载Java SE10的版本) JDK下载完 ...

  10. spring boot 入口源码分析

    public ConfigurableApplicationContext run(String... args) { StopWatch stopWatch = new StopWatch(); / ...