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较为准确,可以根据个人电脑的分辨率来调整"""