基于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双精度浮点数运算并分行显示操作示例
Jul 21 Python
python中import reload __import__的区别详解
Oct 16 Python
python的Tqdm模块的使用
Jan 10 Python
Pycharm 操作Django Model的简单运用方法
May 23 Python
python中单下划线_的常见用法总结
Jul 10 Python
django框架forms组件用法实例详解
Dec 10 Python
Spring Cloud Feign高级应用实例详解
Dec 10 Python
使用python+poco+夜神模拟器进行自动化测试实例
Apr 23 Python
Python垃圾回收机制三种实现方法
Apr 27 Python
Django 如何使用日期时间选择器规范用户的时间输入示例代码详解
May 22 Python
pandas中DataFrame数据合并连接(merge、join、concat)
May 30 Python
python批量创建变量并赋值操作
Jun 03 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
Fatal error: Call to undefined function curl_init()解决方法
2010/04/09 PHP
PHP静态文件生成类实例
2014/11/29 PHP
php mysql数据库操作类(实例讲解)
2017/08/06 PHP
PHP函数积累总结
2019/03/19 PHP
laravel实现上传图片的两种方式小结
2019/10/12 PHP
php7 参数、整形及字符串处理机制修改实例分析
2020/05/25 PHP
六款帮助你实现惊艳视差滚动效果的jQuery插件
2012/09/14 Javascript
javascript模拟select,jselect的方法实现
2012/11/08 Javascript
node.js中的http.response.end方法使用说明
2014/12/14 Javascript
基于jQuery实现表格的排序
2016/12/02 Javascript
Bootstrap基本组件学习笔记之下拉菜单(7)
2016/12/07 Javascript
jQuery+HTML5实现弹出创意搜索框层
2016/12/29 Javascript
js replace替换字符串同时替换多个方法
2018/11/27 Javascript
vue动态绑定class的几种常用方式小结
2019/05/21 Javascript
vue 实现LED数字时钟效果(开箱即用)
2019/12/08 Javascript
Python写的一个简单DNS服务器实例
2014/06/04 Python
在Django的模型中执行原始SQL查询的方法
2015/07/21 Python
Python快速排序算法实例分析
2017/11/29 Python
Python判断字符串是否xx开始或结尾的示例
2019/08/08 Python
在Django admin中编辑ManyToManyField的实现方法
2019/08/09 Python
python运用sklearn实现KNN分类算法
2019/10/16 Python
如何基于python3和Vue实现AES数据加密
2020/03/27 Python
使用Keras实现简单线性回归模型操作
2020/06/12 Python
python 递归相关知识总结
2021/03/03 Python
HTML5打开手机扫码功能及优缺点
2017/11/27 HTML / CSS
Kivari官网:在线购买波西米亚服装
2018/10/29 全球购物
麦当劳印度网上订餐:McDelivery
2020/03/16 全球购物
中科软测试工程师面试题
2012/06/16 面试题
高中竞选班长演讲稿
2014/04/24 职场文书
个人投资计划书
2014/05/01 职场文书
计算机相关专业自荐信
2014/07/02 职场文书
公务员爱岗敬业演讲稿
2014/08/26 职场文书
推普周国旗下讲话稿
2014/09/21 职场文书
2014年党务工作总结
2014/11/25 职场文书
个人工作表现自我评价
2015/03/06 职场文书
Java 关于String字符串原理上的问题
2022/04/07 Java/Android