前兩天需要自動化登入一個商城的後臺 用的是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的強大)
測試圖片
https://img2020.cnblogs.com/blog/1776613/202201/1776613-20220104104600734-2080308296.jpg
https://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>