前言
滑塊拼圖驗證碼的失敗難度在于每次圖片上缺口位置不一樣,需識別圖片上拼圖的缺口位置,使用python的OpenCV庫來識別到
環境準備
pip 安裝 opencv-python
pip installl opencv-python
OpenCV(Open Source Computer Vision Library)是一個開源的計算機視覺庫,提供了很多處理圖片、視頻的方法。
OpenCV庫提供了一個方法(matchTemplate()):從一張較大的圖片中搜索一張較小圖片,計算出這張大圖上各個區域和小圖相似度。
調用這個方法后返回一個二維數組(numpy庫中ndarray對象),從中就能拿到最佳匹配區域的坐標。
這種使用場景就是滑塊驗證碼上背景圖片是大圖,滑塊是小圖。
準備2張圖片
場景示例

先摳出2張圖片,分別為background.png 和 target.png


計算缺口位置
import cv2
# 作者-上海悠悠 QQ交流群:717225969
# blog地址 https://www.cnblogs.com/yoyoketang/
def show(name):
'''展示圈出來的位置'''
cv2.imshow('Show', name)
cv2.waitKey(0)
cv2.destroyAllWindows()
def _tran_canny(image):
"""消除噪聲"""
image = cv2.GaussianBlur(image, (3, 3), 0)
return cv2.Canny(image, 50, 150)
def detect_displacement(img_slider_path, image_background_path):
"""detect displacement"""
# # 參數0是灰度模式
image = cv2.imread(img_slider_path, 0)
template = cv2.imread(image_background_path, 0)
# 尋找最佳匹配
res = cv2.matchTemplate(_tran_canny(image), _tran_canny(template), 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 = image.shape[::-1] # 寬高
cv2.rectangle(template, (x, y), (x + w, y + h), (7, 249, 151), 2)
show(template)
return top_left
if __name__ == '__main__':
top_left = detect_displacement("target.png", "background.png")
print(top_left)
運行效果看到黑色圈出來的地方就說明找到了缺口位置

調試完成后去掉 show 的這部分代碼
# 展示圈出來的區域
# x, y = max_loc # 獲取x,y位置坐標
# w, h = image.shape[::-1] # 寬高
# cv2.rectangle(template, (x, y), (x + w, y + h), (7, 249, 151), 2)
# show(template)
缺口的位置只需得到橫坐標,距離左側的位置top_left為184
參考博客:
https://zhuanlan.zhihu.com/p/65309386
https://blog.csdn.net/weixin_42081389/article/details/87935735
https://blog.csdn.net/qq_30815237/article/details/86812716
ps:python opencv破解滑動驗證碼之獲取缺口位置的示例代碼
破解滑塊驗證碼的思路主要有2種:
- 一張完整的背景圖和一張有缺口的圖片的場景,解決思路:兩張圖片同一個坐標位置進行像素上的一一對比,找出不一樣的坐標。
- 一張有缺口的圖片和需要驗證的小圖,解決思路:1.兩張圖片進行二極化以及歸一化,確定小圖在圖片中間的坐標。這種辦法我沒有驗證通過,可以參考這里。2.通過opencv獲得缺口位置
- 之后就要使用初中物理知識了,使用先加速后減速模仿人手動拖動
- 通過opencv獲得圖片的缺口位置
#coding=utf-8
import cv2
import numpy as np
from PIL import Image
def get_element_slide_distance():
otemp = 'captcha2.png'
oblk = 'captcha1.png'
target = cv2.imread(otemp, 0) # 讀取進行色度圖片,轉換為numpy中的數組類型數據
template = cv2.imread(oblk, 0)
width, height = target.shape[::-1] # 獲取缺口圖數組的形狀 -->缺口圖的寬和高
temp = 'temp.jpg' # 將處理之后的圖片另存
targ = 'targ.jpg'
cv2.imwrite(temp, template)
cv2.imwrite(targ, target)
target = cv2.imread(targ) # 讀取另存的滑塊圖
target = cv2.cvtColor(target, cv2.COLOR_BGR2GRAY) # 進行色彩轉換
# 去除白色部分 獲取滑塊正常大小
target = target[target.any(1)]
target = abs(255 - target) # 獲取色差的絕對值
cv2.imwrite(targ, target) # 保存圖片
target = cv2.imread(targ) # 讀取滑塊
template = cv2.imread(temp) # 讀取背景圖
result = cv2.matchTemplate(target, template, cv2.TM_CCOEFF_NORMED) # 比較兩張圖的重疊區域
top, left = np.unravel_index(result.argmax(), result.shape) # 獲取圖片的缺口位置
#缺口位置
print((left, top, left + width, top + height)) # 背景圖中的圖片缺口坐標位置
#調用PIL Image 做測試
image = Image.open("captcha1.png")
rectangle = (left + 3, top + 3, left + width - 3, top + height - 3) #去掉白色塊的影響(上面去掉白色部分的功能并沒有真的起作用)
#切割
imagecrop = image.crop(rectangle)
#保存切割的缺口
imagecrop.save("new_image.jpg")
return left+3
distance = get_element_slide_distance()
# 滑動距離誤差校正,滑動距離*圖片在網頁上顯示的縮放比-滑塊相對的初始位置
distance = distance*(280/680) - 22
拖動軌跡
def generate_tracks1(XCoordinates):
element = browser.find_element_by_xpath("http://div[@class='secsdk-captcha-drag-icon sc-jKJlTe fsBatO']")
ActionChains(browser).click_and_hold(on_element = element).perform()
#
# ActionChains(browser).move_by_offset(xoffset=0, yoffset=y - 445).perform()
#
# time.sleep(0.15)
# print("第二步,拖動元素")
distance = XCoordinates - 60
# 初速度
v = 0
# 單位時間為0.2s來統計軌跡,軌跡即0.2內的位移,越低看起來越絲滑??!
t = 0.08
# 位移/軌跡列表,列表內的一個元素代表0.2s的位移
tracks = []
# 當前的位移
current = 0
# 到達mid值開始減速
mid = distance * 5 / 8
distance += 10 # 先滑過一點,最后再反著滑動回來
# a = random.randint(1,3)
while current distance:
if current mid:
# 加速度越小,單位時間的位移越小,模擬的軌跡就越多越詳細
a = random.randint(100, 200) # 加速運動
else:
a = -random.randint(2, 10) # 減速運動
# 初速度
v0 = v
# 0.2秒時間內的位移
s = v0 * t + 0.5 * a * (t ** 2)
# 當前的位置
current += s
# 添加到軌跡列表
tracks.append(round(s))
# 速度已經達到v,該速度作為下次的初速度
v = v0 + a * t
if current > distance:
break
# 反著滑動到大概準確位置
# for i in range(4):
# tracks.append(-random.randint(1, 3))
# for i in range(4):
# tracks.append(-random.randint(1,3))
random.shuffle(tracks)
count = 0
for item in tracks:
print(item)
count += item
ActionChains(browser).move_by_offset(xoffset = item, yoffset = random.randint(-2, 2)).perform()
# ActionChains(browser).move_to_element_with_offset(to_element=element, xoffset=XCoordinates-18,yoffset=y - 445).perform()
# time.sleep(2)
# # 釋放鼠標
print(count)
ActionChains(browser).release(on_element = element).perform()
到此這篇關于python3 使用OpenCV計算滑塊拼圖驗證碼缺口位置的文章就介紹到這了,更多相關python滑塊拼圖驗證碼內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持腳本之家!
您可能感興趣的文章:- Python中的異常類型及處理方式示例詳解
- python實現郵箱發送信息
- Python Pytest裝飾器@pytest.mark.parametrize詳解
- 詳解python關于多級包之間的引用問題
- 一些讓Python代碼簡潔的實用技巧總結
- 利用Python讀取微信朋友圈的多種方法總結
- python庫sklearn常用操作
- Python使用psutil庫對系統數據進行采集監控的方法
- python編寫adb截圖工具的實現源碼
- Python爬蟲技術