普通滑动验证

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. 日志文件的配置----【logback-spring.xml】

    一.引入相关包 <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-c ...

  2. Spring Beans 自动装配 简介

    Beans 自动装配 Spring 容器可以在不使用<constructor-arg>和<property> 元素的情况下自动装配相互协作的 bean 之间的关系,这有助于减少 ...

  3. 五、数据类型(1):整数&&带小数点的数

    1.整数 int printf("%d",...); scanf("%d",&...); 2.带小数点的数 double printf("%f ...

  4. xshell使用技巧

    XShell是一款Windows下的一款远程连接Linux主机的工具,类似的软件还有SecureCRT,putty等,但是个人感觉XShell好用,功能强大.. 一.复制和粘贴 linux的Shell ...

  5. ztree实用教程

    首先导入ztree ztree是建立在jquery的基础上的 <link href="js/zTree_v3-master/css/zTreeStyle/zTreeStyle.css& ...

  6. PIC单片机的定时器

    PIC单片机的定时器有3个 timer0 timer1 timer2 定时器的计算方法 256*k*Tcy=定时时间 (256-Init-value)*k*Tcy=定时时间

  7. Matlab GUI程序设计入门——信号发生器+时域分析

    背景:学习matlab gui编程入门,完成一个基于GUIDE的图形化界面程序,结合信号生成及分析等. 操作步骤: 1.新建程序 新建一个GUIDE程序 这里选择第一个选项,即创建一个空白的GUIDE ...

  8. jchdl - GSL实例 - Mux4(使用WireVec简化输入线声明)

    https://mp.weixin.qq.com/s/yJx_dV6ScUStJtPWVuD38w 原理图 ​​ 参考链接 https://github.com/wjcdx/jchdl/blob/ma ...

  9. 手写 new

    /* 基于内置的 new 关键词,我们可以创建 Dog 的一个实例 zhangsan ,实例可以调用原型上的属性和方法 需求:自己实现一个 _new 方法,也可以模拟出内置 new 后的结果 */ / ...

  10. UML ——六种依赖关系.md

    在UML类图中,常见的有以下几种关系: 泛化(Generalization), 实现(Realization), 关联(Association), 聚合(Aggregation), 组合(Compos ...