普通滑动验证

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. 容器技术之Docker网络

    上一篇博客我们主要聊了下docker镜像相关的说明以及怎样基于现有镜像制作镜像.分发镜像到docker仓库中的相关测试:回顾请参考https://www.cnblogs.com/qiuhom-1874 ...

  2. docker的file内容解释

    关键字---重点啊) FROM 基础镜像,当前新镜像是基于哪个镜像的 MAINTAINER  镜像维护者的姓名和邮箱地址 RUN  容器构建时需要运行的命令 EXPOSE 当前容器对外暴露的端口 WO ...

  3. mybatis是怎样炼成的

    前言 一些个人感受:不管分析什么源码,如果我们能摸索出作者的心路历程,跟着他的脚步一步一步往前走,这样才能接近事实的真相,也能更平滑更有趣的学习到知识.跟福尔摩斯探案一样,作者都经历了些什么,为什么他 ...

  4. 1700人点反对的LeetCode问题,是因为太难了吗?

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是LeetCode专题的第40篇文章,我们一起来看的是LeetCode中的71题Simplify Path,中文名是简化路径. 这题的难 ...

  5. JavaScript之倔强的字符串

    关于倔强的JavaScript字符串:不可以被修改 我们是字符串 我们的口号是:你可以消灭我,但是你不能改变我 JavaScript字符串是不可改变的,当真是这样的吗? 让我们来试验一下. var n ...

  6. 彻底理解JavaScript ES6中的import和export

    0.前言 前端工程,在最早的时候是没有模块的概念的.随着前端工程的发展,前端开发也越来越规范化,更像是软件工程了.那么随之而来的,为了解决工程化的问题,就引入了模块的概念.但是在早期,因为ecmasc ...

  7. [书籍分享]0-001.rework(重来:更为简单有效的商业思维)

    封面    内容简介 大多数的企业管理的书籍都会告诉你:制定商业计划.分析竞争形势.寻找投资人等等.如果你要找的是那样的书,那么把这本书放回书架吧. 这本书呈现的是一种更好.更简单的经商成功之道.读完 ...

  8. SpringBoot的 HelloWorld

    SpringBoot HelloWorld 功能需求 ​ 浏览器发送hello请求,服务器接收请求并处理,相应HelloWorld字符串 1.创建一个maven工程:(jar) 2.导入SpringB ...

  9. SpringAOP使用及源码分析(SpringBoot下)

    一.SpringAOP应用 先搭建一个SpringBoot项目 <?xml version="1.0" encoding="UTF-8"?> < ...

  10. 管程(Monitor)概念及Java的实现原理

    互斥 互斥访问是并发编程要解决的核心问题之一. 有许多种方法可以满足临界区的互斥访问.大体上可以分为三种, 一种是软件方法,即由用户程序承担互斥访问的责任,而不需要依赖编程语言或操作系统,譬如Dekk ...