基于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转码问题的解决方法
Oct 07 Python
初学python数组的处理代码
Jan 04 Python
在Python程序中操作MySQL的基本方法
Jul 29 Python
Python输出由1,2,3,4组成的互不相同且无重复的三位数
Feb 01 Python
python实现简单神经网络算法
Mar 10 Python
Python3随机漫步生成数据并绘制
Aug 27 Python
linux中如何使用python3获取ip地址
Jul 15 Python
python使用pandas处理excel文件转为csv文件的方法示例
Jul 18 Python
python selenium 查找隐藏元素 自动播放视频功能
Jul 24 Python
python实现简单俄罗斯方块
Mar 13 Python
python中的时区问题
Jan 14 Python
python实现黄金分割法的示例代码
Apr 28 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
PHP学习笔记(二):变量详解
2015/04/17 PHP
PHP获取真实客户端的真实IP
2017/03/07 PHP
php 获取xml接口数据的处理方法
2018/05/31 PHP
为Plesk PHP7启用Oracle OCI8扩展方法总结
2019/03/29 PHP
做网页的一些技巧
2007/02/01 Javascript
JavaScript Prototype对象
2009/01/07 Javascript
告诉你什么是javascript的回调函数
2014/09/04 Javascript
JavaScript更改原始对象valueOf的方法
2015/03/19 Javascript
javascript实现C语言经典程序题
2015/11/29 Javascript
Node.js的Web模板引擎ejs的入门使用教程
2016/06/06 Javascript
使用vue框架 Ajax获取数据列表并用BootStrap显示出来
2017/04/24 Javascript
如何更好的编写js async函数
2018/05/13 Javascript
使用electron制作满屏心特效的示例代码
2018/11/27 Javascript
Vue入门学习笔记【基本概念、对象、过滤器、指令等】
2019/04/13 Javascript
javascript中如何判断类型汇总
2019/05/14 Javascript
vue 实现通过vuex 存储值 在不同界面使用
2019/11/11 Javascript
JavaScript缺少insertAfter解决方案
2020/07/03 Javascript
详解python项目实战:模拟登陆CSDN
2019/04/04 Python
python psutil监控进程实例
2019/12/17 Python
使用Python来做一个屏幕录制工具的操作代码
2020/01/18 Python
Python基于jieba, wordcloud库生成中文词云
2020/05/13 Python
python实现梯度下降算法的实例详解
2020/08/17 Python
python speech模块的使用方法
2020/09/09 Python
详解pycharm自动import所需的库的操作方法
2020/11/30 Python
五分钟学会怎么用python做一个简单的贪吃蛇
2021/01/12 Python
Crocs波兰官方商店:女鞋、男鞋、童鞋、洞洞鞋
2019/10/08 全球购物
介绍一下HTTP、HTTPS和SSL
2012/12/16 面试题
标记环介质访问控制协议
2016/03/27 面试题
电子商务应届生求职信
2013/11/16 职场文书
运动会广播稿20字
2014/02/18 职场文书
报告会主持词
2014/04/02 职场文书
2014年测量员工作总结
2014/12/12 职场文书
物流仓管员岗位职责
2015/04/01 职场文书
2015年中职班主任工作总结
2015/05/25 职场文书
小学少先队工作总结2015
2015/05/26 职场文书
python中pycryto实现数据加密
2022/04/29 Python