playwright–自動化(二):過滑塊驗證碼 驗證碼缺口識別

前兩天需要自動化登錄一個商城的後台 用的是playwright 沒有用selenium 中間出了一個滑塊驗證 現階段playwright教程不是太多,自己做移動的時候各種找,費勁巴拉的。現在自己整出來了就記錄一下吧!

如過幫助到了可否關注推薦分享 來個三連?

樣式~大概這個樣子


上流程,首先缺口獲取

#沒有用過opencv的cv2導入報錯的  可以安裝
#pip install opencv-python

import cv2
def get_notch_location(hx, bg):
    '''
    根據文件進行識別
    :param hx: 滑塊圖片的文件路徑
    :param bg: 背景圖片的文件路徑
    :return:
    '''
    bg_img = cv2.imread(hx,0)
    tp_img = cv2.imread(bg,0)  # 讀取到兩個圖片,進行灰值化處理
    img = cv2.imread(bg)  # 讀取圖片畫框直觀可以看到,上邊是灰度的所以重新打開一個原圖
    res = cv2.matchTemplate(_tran_canny(bg_img), _tran_canny(tp_img), cv2.TM_CCOEFF_NORMED)
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
    top_left = max_loc[0]  # 橫坐標
    # 展示圈出來的區域
    x, y = max_loc  # 獲取x,y位置坐標
    w, h = bg_img.shape[::-1]  # 寬高
    #矩形畫圖
    cv2.rectangle(img, (x, y), (x + w, y + h), (0,0,255), 2)
    #顯示
    cv2.imshow('Show', name)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    #這個是滑塊要移動的距離
    return top_left

測試一下(包括肉眼看不太清楚的同樣可以不得不說opencv的強大)

測試圖片
//img2020.cnblogs.com/blog/1776613/202201/1776613-20220104104600734-2080308296.jpg

//img2020.cnblogs.com/blog/1776613/202201/1776613-20220104110557885-1084215972.jpg


下邊軌跡移動(其實就是移動距離分了好多步)

#有的檢測移動速度的 如果勻速移動會被識別出來,來個簡單點的 漸進
 def get_track(distance):  # distance為傳入的總距離
    # 移動軌跡
    track = []
    # 當前位移
    current = 0
    # 減速閾值
    mid = distance * 4 / 5
    # 計算間隔
    t = 0.2
    # 初速度
    v = 1

    while current < distance:
        if current < mid:
            # 加速度為2
            a = 4
        else:
            # 加速度為-2
            a = -3
        v0 = v
        # 當前速度
        v = v0 + a * t
        # 移動距離
        move = v0 * t + 1 / 2 * a * t * t
        # 當前位移
        current += move
        # 加入軌跡
        track.append(round(move))
    return track

接下來就是重點了(說是重點簡單的雅痞)

#移動滑塊
#首先咱們的找到要移動的東西吧
s = self.page.wait_for_selector('//div[@class="_3CvVPX _3gznAC _3BUN_s"]',strict=True)
#找到這個元素再當前頁面的坐標(這個會返回一個字典裡邊四個數字)
box = s.bounding_box()
#移動滑鼠到上邊元素的中心(上邊四個參數用途來了)
self.page.mouse.move(box["x"] + box["width"] / 2, box["y"] + box["height"] / 2)
#按下滑鼠(這個不多說)
self.page.mouse.down()
#這裡獲取到x坐標中心點位置
x = box["x"] + box["width"] / 2
#這個把缺口獲取到的長度放到軌跡加工一下得到一個軌跡
tracks = get_track(top_left)
for track in tracks:
  #循環滑鼠按照軌跡移動
  #strps 是控制單次移動速度的比例是1/10 默認是1 相當於 傳入的這個距離不管多遠0.1秒鐘移動完 越大越慢
  self.page.mouse.move(x + track, 0,steps=10)
  x += track
#移動結束滑鼠抬起
self.page.mouse.up()
當滑鼠抬起呢一刻 你就可以心裡石頭落地了,他過了
控制好速度 反正我這基本都能過

下邊給一個html 可以自己測試的頁面(其實扒拉別人的)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
 <div class="box">
    <div class="btn">>></div>
    <p class="text">拖動滑塊驗證</p>
    <div class="bg"></div>
  </div>

 <style>
   * {
  margin: 0;
  padding: 0;
  background-color: #ffffff;
}

.box {
  width: 500px;
  height: 60px;
  position: relative;
  left: 50%;
  margin-left: -250px;
  margin-top: 50px;
  background: #eae4e4;
  display: flex;
  align-items: center;
  -webkit-user-select:none;
  -moz-user-select:none;
  -ms-user-select:none;
  user-select:none;
}
.btn {
  height: 100%;
  width: 60px;
  background: #fbf5f5;
  box-sizing: border-box;
  border: 2px solid #cecaca;
  position: absolute;
  left: 0;
  top: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 25px;
  color: #d5d4d4;
  z-index: 999;
  -webkit-user-select:none;
  -moz-user-select:none;
  -ms-user-select:none;
  user-select:none;
}
.btn:hover {
  cursor:pointer;
}
.text {
  font-size: 20px;
  position: absolute;
  left: 50%;
  margin-left: -60px;
  background-color: transparent;
  z-index: 2;
}
.bg {
  height: 100%;
  position: absolute;
  background-color: #4cbb42;
  z-index: 1;
}
 </style>

 <script>
   window.onload = function () {
  // 封裝-選擇器,內部可以做兼容性
  function querySelect(name) {
    return document.querySelector(name)
  }
  // 驗證成功
  // 驗證失敗
  // 觸發事件 onmousedown按下  onmousemove移動  onmouseup鬆開
  let btn = querySelect('.btn') // 滑塊  對IE6/7 有兼容性問題
  let box = querySelect('.box') // box
  let text = querySelect('.text') // 文字
  let bg = querySelect('.bg') // 背景
  btn.onmousedown = (eventDown) => {
    // event.clientX;clientY   滑鼠當前X軸Y軸坐標
    let downX = eventDown.clientX
    console.log(downX)
    document.onmousemove = (eventMove) => {
      // 移動的X坐標 - 按下的X坐標

      let moveX = eventMove.clientX - downX
        console.log(eventDown.clientX)
        console.log(moveX)
      let boxWidth = box.offsetWidth
      let btnWidth = btn.offsetWidth
      if (moveX >= 0 && moveX <= (boxWidth - btnWidth)) { // 可移動的範圍
        btn.style.left = moveX + 'px' // 滑塊絕對定位
        bg.style.width = moveX + 'px' // 設備背景的寬度
      }
      if (moveX >= (boxWidth - btnWidth)) {
        btn.style.left = (boxWidth - btnWidth) + 'px' // 滑塊絕對定位
        bg.style.width = (boxWidth - btnWidth) + 'px' // 設備背景的寬度
        // 文字提醒
        text.innerText = '驗證成功'
        text.style.color = '#fff'
        // 事件清除-按下、移動
        btn.onmousedown = null
        document.onmousemove = null
        btn.onmouseup = null
      }
    }
  }
  btn.onmouseup = (eventUp) => {
    // 鬆開後回到原點
    // 清除移動事件
      console.log('滑鼠抬起')
    btn.style.left = 0 + 'px'
    bg.style.width = 0 + 'px'
    document.onmousemove = null
  }
}
 </script>


</body>
</html>