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

基于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()

效果图

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

滑动验证码

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

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滑动验证码内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • selenium+java破解极验滑动验证码的示例代码

    摘要 分析验证码素材图片混淆原理,并采用selenium模拟人拖动滑块过程,进而破解验证码. 人工验证的过程 1.打开威锋网注册页面 2.移动鼠标至小滑块,一张完整的图片会出现(如下图1) 3.点击鼠标左键,图片中间会出现一个缺块(如下图2) 4.移动小滑块正上方图案至缺块处 5.验证通过 selenium模拟验证的过程 加载威锋网注册页面 下载图片1和缺块图片2 根据两张图片的差异计算平移的距离x 模拟鼠标点击事件,点击小滑块向右移动x 验证通过 详细分析 1.打开chrome浏览器控制台,会

  • Java selenium处理极验滑动验证码示例

    要爬取一个网站遇到了极验的验证码,这周都在想着怎么破解这个,网上搜了好多知乎上看到有人问了这问题,我按照这思路去大概实现了一下. 1.使用htmlunit(这种方式我没成功,模拟鼠标拖拽后轨迹没生成,可以跳过) 我用的是java,我首先先想到了用直接用htmlunit,我做了点初始化 private void initWebClient() { if (webClient != null) { return; } webClient = new WebClient(BrowserVersion.

  • selenium+Chrome滑动验证码破解二(某某网站)

    具体详情见代码,研究网站,随便输入手机号点击获取验证码 在自己写代码前参考了一批博客,是把所有验证码图片截取所有验证码图片保存在本地,再对比,感觉方法不行,所以自己写了个破解方法,通过js修改css直接抓取完整图片,因为上一篇写了B站,这里就不一一分析了,直接上代码: 破解成功界面 完整代码: # -*- coding:utf-8 -*- ''' 研究网站: https://account.ch.com/NonRegistrations-Regist 滑块验证码也分两种: 1.直接给缺口图片,先

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

    基于selenium进行动作链 由于最近很多人聊到滑动验证码怎么处理,所以决定自己动手试一下. 做一个东西前.我们首先要对这个东西的操作过程有一个大概的了解. 打开验证码页面. 鼠标放到拖动按钮上 对拖动按钮进行拖动 拖动到阴影快重合的位置. 放开拖动按钮. from selenium import webdriver from selenium.webdriver.common.action_chains import ActionChains artice = browser.find_el

  • 使用Python的OpenCV模块识别滑动验证码的缺口(推荐)

    最近终于找到一个好的方法,使用Python的OpenCV模块识别滑动验证码的缺口,可以将滑动验证码中的缺口识别出来了. 测试使用如下两张图片: target.jpg template.png 现在想要通过"template.png"在"target.jpg"中找到对应的缺口,代码实现如下: # encoding=utf8 import cv2 import numpy as np def show(name): cv2.imshow('Show', name) cv

  • 基于C#实现图片滑动验证码的示例代码

    目录 图片准备 合成目标 实现 1.创建项目 2.Nuget添加ImageSharp 3.vscode打开 4.引入图片 5.生成out_bg.jpg 6.生成out_slider.png 全部代码 最后 图片准备 hole.png和slider.png为png是因为图片带有透明度. 合成目标 最终为前端生成两张图片: out_slider.png高度为344与背景图等高. 也可以打开滑动验证Demo页面,F12来观察图片. 实现 本机环境为.net 6.0.300-preview.22204.

  • 基于python实现破解滑动验证码过程解析

    前言: 很多小伙伴们反馈,在web自动化的过程中,经常会被登录的验证码给卡住,不知道如何去通过验证码的验证.今天专门给大家来聊聊验证码的问题,一般的情况下遇到验证码我们可以都可以找开发去帮忙解决,关闭验证码,或者给一个万能的验证码!那么如果开发不提供帮助的话,我们自己有没有办法来处理这些验证码的问题呢?答案当然是有的,常见的验证码一般分为两类,一类是图文验证码,一类是滑动验证码! 今天我们主要来聊聊滑动验证码如何去识别破解. 滑动验证破解思路 关于滑动验证码破解的思路大体上来讲就是以下两个步骤:

  • 使用java + selenium + OpenCV破解腾讯防水墙滑动验证码功能

    * 验证码地址:https://007.qq.com/online.html * 使用OpenCv模板匹配 * 成功率90%左右 * Java + Selenium + OpenCV 产品样例 来吧!展示! 注意!!! · 在模拟滑动时不能按照相同速度或者过快的速度滑动,需要向人滑动时一样先快后慢,这样才不容易被识别. 模拟滑动代码↓↓↓ /** * 模拟人工移动 * @param driver * @param element页面滑块 * @param distance需要移动距离 */ pu

  • 使用java + selenium + OpenCV破解网易易盾滑动验证码的示例

    网易易盾:dun.163.com * 验证码地址:https://dun.163.com/trial/jigsaw * 使用OpenCv模板匹配 * Java + Selenium + OpenCV 产品样例 接下来就是见证奇迹的时刻! 注意!!! · 在模拟滑动时不能按照相同速度或者过快的速度滑动,需要向人滑动时一样先快后慢,这样才不容易被识别. 模拟滑动代码↓↓↓ /** * 模拟人工移动 * @param driver * @param element页面滑块 * @param dista

  • OpenCV结合selenium实现滑块验证码

    本次案例使用OpenCV和selenium来解决一下滑块验证码 先说一下思路: 弹出滑块验证码后使用selenium元素截图将验证码整个背景图截取出来 将需要滑动的小图单独截取出来,最好将小图与背景图顶部的像素距离获取到,这样可以将背景图上下多余的边框截取掉 使用OpenCV将背景图和小图进行灰度处理,并对小图再次进行二值化全局阈值,这样就可以利用OpenCV在背景图中找到小图所在的位置 用OpenCV获取到相差的距离后利用selenium的鼠标拖动方法进行拖拉至终点. 详细步骤: 先获取验证码

  • python基于opencv批量生成验证码的示例

    基本思路是使用opencv来把随机生成的字符,和随机生成的线段,放到一个随机生成的图像中去. 虽然没有加复杂的形态学处理,但是目前看起来效果还不错 尝试生成1000张图片,但是最后只有998张,因为有有重复的,被覆盖掉了. 代码如下: import cv2 import numpy as np line_num = 10 pic_num = 1000 path = "./imgs/" def randcolor(): return (np.random.randint(0,255),n

随机推荐