基于opencv的selenium滑动验证码的实现


Posted in Python onJuly 24, 2020

基于selenium进行动作链

由于最近很多人聊到滑动验证码怎么处理,所以决定自己动手试一下。
做一个东西前。我们首先要对这个东西的操作过程有一个大概的了解。

  • 打开验证码页面。
  • 鼠标放到拖动按钮上
  • 对拖动按钮进行拖动
  • 拖动到阴影快重合的位置。
  • 放开拖动按钮。
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains

artice = browser.find_element_by_class_name('geetest_slider_button') # 滑动按钮
action = ActionChains(browser)
action.click_and_hold(artice).perform() #按住按钮不放
action.reset_actions() 
action.pause(0.01).move_by_offset(step, 0).perform() #step 为滑动的水平距离
action.release(artice).perform() # 松开按钮

上面就是本方用到的有关于ActionChains的方法。其他方法这里不过多介绍,想了解更多的请转seleniun ActionChains 鼠标键盘操作

接下来到我本次要介绍的重点,滑动距离的介绍,也就是图片求阴影区域的位置。

这里我使用了opencv库,主要流程包括

  • 对图像二值化
  • 对二值化的图像进行高斯模糊
  • 用canny进行边缘检测
  • 然后HoughLinesP霍夫变换寻找直线
  • 对符合条件的直线进行处理寻找交点,进而求出我们要找的阴影快的距离
import cv2 as cv
import numpy as np
import math

# 寻找直线
def FindLines(image):
 image = cv.cvtColor(image, cv.COLOR_BGR2GRAY) # 二值化
 blurred = cv.GaussianBlur(image, (5, 5), 0) # 高斯模糊
 canny = cv.Canny(blurred, 200, 400) # canny边缘检测
 lines = cv.HoughLinesP(canny, 1, np.pi / 180, 20, minLineLength=15, maxLineGap=8) # 霍夫变换寻找直线
 return lines[:, 0, :] # 返回直线


# 这里对直线进行过滤
def FindResultLises(lines):
 resultLines = []
 for x1, y1, x2, y2 in lines:
  if (abs(y2 - y1) < 5 or abs(x2 - x1) < 5) and min(x1, x2) > 60: # 只要垂直于坐标轴的直线并且起始位置在60像素以上
   resultLines.append([x1, y1, x2, y2])
 return resultLines


# 判断点是否在直线上
def distAbs(point_exm, list_exm):
 x, y = point_exm
 x1, y1, x2, y2 = list_exm
 dist_1 = math.sqrt(abs((y2 - y1) + (x2 - x1) + 1)) # 直线的长度
 dist_2 = math.sqrt(abs((y1 - y) + (x1 - x) + 1)) + math.sqrt(abs((y2 - y) + (x2 - x) + 1)) # 点到两直线两端点距离和
 return abs(dist_2 - dist_1) 


# 交点函数 y = kx + b 求交点位置
def findPoint(line1, line2):
 poit_status = False
 x1, y1, x2, y2 = line1
 x3, y3, x4, y4 = line2
 x = y = 0

 if (x2 - x1) == 0: # 垂直x轴
  k1 = None
  b1 = 0
 else:
  k1 = 1.0 * (y2 - y1) / (x2 - x1)
  b1 = y1 * 1.0 - k1 * x1 * 1.0

 if (x4 - x3) == 0:
  k2 = None
  b2 = 0
 else:
  k2 = 1.0 * (y4 - y3) / (x4 - x3)
  b2 = y3 * 1.0 - k2 * x3 * 1.0

 if k1 is None:
  if not k2 is None:
   x = x1
   y = k2 * x1 + b2
   poit_status = True
 elif k2 is None:
  x = x3
  y = k1 * x3 + b1
  poit_status = True
 elif k1 != k2:
  x = (b2 - b1) * 1.0 / (k1 - k2)
  y = k1 * x * 1.0 + b1 * 1.0
  poit_status = True

 return poit_status, [x, y]


# 求交点
def linePoint(resultLines):
 for x1, y1, x2, y2 in resultLines:
  for x3, y3, x4, y4 in resultLines:
   point_is_exist, [x, y] = findPoint([x1, y1, x2, y2], [x3, y3, x4, y4]) # 两线是否有交点
   if point_is_exist:
    dist_len1 = distAbs([x, y], [x1, y1, x2, y2])
    dist_len2 = distAbs([x, y], [x3, y3, x4, y4])
    if dist_len1 < 5 and dist_len2 < 5: # 如果误差在5内我们认为点在直线上
     # 判断交点在行直线中是左端点还是右端点
     if abs(y2 - y1) < 5:
      # x1是行直线
      if abs(x1 - x) + abs(y1 - y) < 5: # 左端点
       return -1, [x, y]
      else:
       return 1, [x, y]
     else:
      # x2是行直线
      if abs(x3 - x) + abs(y3 - y) < 5:
       return -1, [x, y]
      else:
       return 1, [x, y]
 return 0, [0, 0]

if __name__ == '__main__':
 img = cv.imread(r'C:\Users\Administrator\Desktop\opencv\temImg.png')
 lines = FindLines(img)
 lines = FindResultLises(lines)
 L_or_R, point_x = linePoint(lines) # L_or_R 用于判断交点在行直线左边还是右边 后面拖动要用到
 xoffset = point_x[0]
 yoffset = point_x[1]
 cv.circle(img, (int(xoffset), int(yoffset)), 5, (0, 0, 255), 3)
 cv.imshow('circle', img)
 cv.waitKey(0)
 cv.destroyAllWindows()

基于opencv的selenium滑动验证码的实现

基于opencv的selenium滑动验证码的实现

效果图

当然也有操作不到的图片,各位有兴趣的可以尝试并且修改其中的参数

滑动验证码

在上面我们已经找到了边缘点,并且根据交点是在左边还是右边进行计算,找到我们要滑动的最后值

if L_or_R == 1:
 x_offset = xoffset - 20 # 20是阴影快一半的长度 可根据实际情况调整
else:
 x_offset = offset + 20

有了滑动距离,接下来就应该是滑动了
如果我们直接用 action.move_by_offset(x_offset,0).perform() 图片会图示被怪物吃了。那就是运动轨迹被检测到不是正常人的行为,因为正常人很难一拉就拉到对应的位置。

滑动轨迹算法

所以我们还要有一个模拟人的正常操作的拖动轨迹:下面是以先加速再减速的轨迹

import ramdom

# 通过加速减速模拟滑动轨迹
def moveTrack(xoffset):
 updistance = xoffset*4/5
 t = 0.2
 v = 0
 steps_list = []
 current_offset = 0
 while current_offset<xoffset:
  if current_offset<updistance:
   a = 2 + random.random() * 2
  else:
   a = -random.uniform(12,13)
  vo = v
  v = vo + a * t
  x = vo * t + 1 / 2 * a * (t * t)
  x = round(x, 2)
  current_offset += abs(x)
  steps_list.append(abs(x))
 # 上面的 sum(steps_list) 会比实际的大一点,所以再模拟一个往回拉的动作,补平多出来的距离
 disparty = sum(steps_list)-xoffset 
 last1 = round(-random.random() - disparty, 2)
 last2 = round(-disparty-last1, 2)
 steps_list.append(last1)
 steps_list.append(last2)
 
 return steps_list

有了轨迹 steps_list 我们就可以通过循环来拖动按钮。需要注意的一点是 每一次循环都要action.reset_actions() 不然他会把之前的距离也算进来,循环结束记得松开按钮

for step in steps_list:
 action.reset_actions()
 action.pause(0.01).move_by_offset(step, 0).perform()
action.release(artice).perform()

到此这篇关于基于opencv的selenium滑动验证码的实现的文章就介绍到这了,更多相关opencv selenium滑动验证码内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python利用拉链法实现字典方法示例
Mar 25 Python
python的变量与赋值详细分析
Nov 08 Python
python的unittest测试类代码实例
Dec 07 Python
Python实现生成随机数据插入mysql数据库的方法
Dec 25 Python
浅析python实现scrapy定时执行爬虫
Mar 04 Python
使用python脚本实现查询火车票工具
Jul 19 Python
使用Python Pandas处理亿级数据的方法
Jun 24 Python
python实现代码统计器
Sep 19 Python
利用PyCharm操作Github(仓库新建、更新,代码回滚)
Dec 18 Python
python随机生成大小写字母数字混合密码(仅20行代码)
Feb 01 Python
python orm 框架中sqlalchemy用法实例详解
Feb 02 Python
python-docx文件定位读取过程(尝试替换)
Feb 13 Python
详解python中GPU版本的opencv常用方法介绍
Jul 24 #Python
python定义类的简单用法
Jul 24 #Python
Python爬虫抓取指定网页图片代码实例
Jul 24 #Python
详解Flask前后端分离项目案例
Jul 24 #Python
通过实例了解Python异常处理机制底层实现
Jul 23 #Python
Python异常处理机制结构实例解析
Jul 23 #Python
使用pygame实现垃圾分类小游戏功能(已获校级二等奖)
Jul 23 #Python
You might like
索尼SONY ICF-7600A(W)电路分析
2021/03/01 无线电
多数据表共用一个页的新闻发布
2006/10/09 PHP
php中json_encode中文编码问题分析
2011/09/13 PHP
php分割合并两个字符串的函数实例
2015/06/19 PHP
用PHP写的一个冒泡排序法的函数简单实例
2016/05/26 PHP
php将服务端的文件读出来显示在web页面实例
2016/10/31 PHP
PHP实现表单提交时去除斜杠的方法
2016/12/26 PHP
作为PHP程序员你要知道的另外一种日志
2018/07/30 PHP
JavaScript QueryString解析类代码
2010/01/17 Javascript
JS实现浏览器状态栏显示时间的方法
2015/10/27 Javascript
Bootstarp风格的toggle效果分享
2016/02/23 Javascript
js定义类的几种方法(推荐)
2016/06/08 Javascript
浅谈JS验证表单文本域输入空格的问题
2017/02/14 Javascript
详解用函数式编程对JavaScript进行断舍离
2017/09/18 Javascript
tween.js缓动补间动画算法示例
2018/02/13 Javascript
vue 点击按钮增加一行的方法
2018/09/07 Javascript
PWA介绍及快速上手搭建一个PWA应用的方法
2019/01/27 Javascript
vue 父组件通过v-model接收子组件的值的代码
2019/10/27 Javascript
Python读写配置文件的方法
2015/06/03 Python
python 寻找list中最大元素对应的索引方法
2018/06/28 Python
一看就懂得Python的math模块
2018/10/21 Python
利用python画出AUC曲线的实例
2020/02/28 Python
Python读入mnist二进制图像文件并显示实例
2020/04/24 Python
Python使用jupyter notebook查看ipynb文件过程解析
2020/06/02 Python
python suds访问webservice服务实现
2020/06/26 Python
在HTML5中使用MathML数学公式的简单讲解
2016/02/19 HTML / CSS
喜诗官方在线巧克力店:See’s Candies
2017/01/01 全球购物
罗马尼亚在线杂货店:Pilulka.ro
2019/09/28 全球购物
巴西最大的运动品牌:Olympikus
2020/07/14 全球购物
行政总监岗位职责
2013/12/05 职场文书
伊琍体标语
2014/06/25 职场文书
学习十八届四中全会精神思想汇报
2014/10/23 职场文书
2014年社区党建工作汇报材料
2014/11/02 职场文书
大学生个人学习总结
2015/02/15 职场文书
2015年幼儿园后勤工作总结
2015/04/25 职场文书
预备党员群众意见
2015/06/01 职场文书