無原圖滑動驗證碼2

import xlwings as xw
import pandas as pd
import datetime
import re
import base64
import cv2
import pathlib
import zipfile
import shutil
def down_pic(data,data_type,path_dic):
    data = data.split(',')[1]
    image_data = base64.b64decode(data)
    file_path=rf"{path_dic['驗證碼存放路徑']}\{data_type}.png"
    with open(file_path, 'wb') as f:
        f.write(image_data)
class SlideCrack(object):
    def __init__(self, gap, bg):
        """
        init code
        :param gap: 缺口圖片
        :param bg: 背景圖片
        """
        self.gap = gap
        self.bg = bg

    @staticmethod
    def clear_white(img):
        # 清除圖片的空白區域,這裏主要清除滑塊的空白
        img = cv2.imread(img)
        rows, cols, channel = img.shape
        min_x = 255
        min_y = 255
        max_x = 0
        max_y = 0
        for x in range(1, rows):
            for y in range(1, cols):
                t = set(img[x, y])
                if len(t) >= 2:
                    if x <= min_x:
                        min_x = x
                    elif x >= max_x:
                        max_x = x

                    if y <= min_y:
                        min_y = y
                    elif y >= max_y:
                        max_y = y
        img1 = img[min_x:max_x, min_y: max_y]
        return img1

    def template_match(self, tpl, target):
        th, tw = tpl.shape[:2]
        result = cv2.matchTemplate(target, tpl, cv2.TM_CCOEFF_NORMED)
        # 尋找矩陣(一維數組當作向量,用Mat定義) 中最小值和最大值的位置
        min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
        tl = max_loc
        br = (tl[0] + tw, tl[1] + th)
        # 繪製矩形邊框,將匹配區域標註出來
        # target:目標圖像
        # tl:矩形定點
        # br:矩形的寬高
        # (0,0,255):矩形邊框顏色
        # 1:矩形邊框大小
        cv2.rectangle(target, tl, br, (0, 0, 255), 2)
        # 暫不輸出
        # cv2.imwrite(self.out, target)
        return tl[0]

    @staticmethod
    def image_edge_detection(img):
        edges = cv2.Canny(img, 100, 200)
        return edges

    def discern(self):
        img1 = self.clear_white(self.gap)
        img1 = cv2.cvtColor(img1, cv2.COLOR_RGB2GRAY)
        slide = self.image_edge_detection(img1)

        back = cv2.imread(self.bg, 0)
        back = self.image_edge_detection(back)

        slide_pic = cv2.cvtColor(slide, cv2.COLOR_GRAY2RGB)
        back_pic = cv2.cvtColor(back, cv2.COLOR_GRAY2RGB)
        x = self.template_match(slide_pic, back_pic)
        # 輸出橫座標, 即 滑塊在圖片上的位置
        return x
# 獲取滑動距離
def get_px(path_dic):
    # 滑塊圖片
    image1 = rf"{path_dic['驗證碼存放路徑']}\small.png"
    # 背景圖片
    image2 = rf"{path_dic['驗證碼存放路徑']}\big.png"
    sc = SlideCrack(image1, image2)
    a = sc.discern()
    return  a
# 獲取位移距離
def get_tracks(distance):
    #distance爲上一步得出的總距離。20是等會要回退的像素
    distance+=20
    #初速度爲0,s是已經走的路程,t是時間
    v0=2
    s=0
    t=0.4
   #mid是進行減速的路程
    mid=distance*3/5
   #存放走的距離
    forward_tracks=[]
    while s<distance:
        if s<mid:
            a=2
        else:
            a=-3
        #高中物理,勻加速路程的計算
        v=v0
        tance=v*t+0.5*a*(t**2)
        tance=round(tance)
        s+=tance
        v0=v+a*t
        forward_tracks.append(tance)
    #因爲回退20像素,所以可以手動打出,只要和爲20即可
    back_tracks = [-1, -1, -1, -2, -2, -2, -3, -3, -2, -2, -1]  # 20
    return {"forward_tracks": forward_tracks, 'back_tracks': back_tracks}
if __name__ == '__main__':
    # 只能是英文路徑
    path_dic={}
    path_dic['驗證碼存放路徑']=r"D:\tem"
    # 下載滑塊圖片.我的案例是base64的數據,獲取數據之後,直接保存就行,要是url,用requests取一下
    down_pic(data, "small", path_dic)
    # 下載缺口圖片
    down_pic(data, "big", path_dic)
    # 獲取滑動距離(總距離)
    distance=get_px(path_dic)
    # 獲取每次移動的距離和回退的距離,防反爬
    dic=get_tracks(distance)
    """根據實際測試,在distance-7px較爲準確,可以根據個人電腦的分辨率來調整"""

  

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章