在使用selenium模拟登录知乎的过程中发现,知乎的验证码是没有原图的,所以无法使用像素匹配找到对应的空缺位置。
这里使用opencv图像匹配识别滑动验证码缺口,具体代码和解释见下,想了解详细信息,参见链接【2022 年】Python3 爬虫教程 - OpenCV 图像匹配识别滑动验证码缺口
首先安装opencv:
pip install opencv-python之后利读取底图和缺口图:
# 读取背景图片和缺口图片
bg_img = cv2.imread('bg.jpg') # 背景图片
tp_img = cv2.imread('tp.png') # 缺口图片为了更好地将缺口与背景匹配,我们首先得识别出图片的边缘:
# 识别图片边缘
bg_edge = cv2.Canny(bg_img, 100, 200)
tp_edge = cv2.Canny(tp_img, 100, 200)这里得到了图片边缘的灰度图,进一步将其图片格式转为RGB格式:
# 转换图片格式
bg_pic = cv2.cvtColor(bg_edge, cv2.COLOR_GRAY2RGB)
tp_pic = cv2.cvtColor(tp_edge, cv2.COLOR_GRAY2RGB)
# 可以查看一下转换后的图片
cv2.imshow('bg', bg_pic)
cv2.imshow('tp', tp_pic)
cv2.waitkeys(0)之后是缺口匹配:
利用cv2中的matchTemplate函数,可以在背景图片中搜索对应的缺口,具体代码如下:
# 缺口匹配
res = cv2.matchTemplate(bg_pic, tp_pic, cv2.TM_CCOEFF_NORMED)res为每个位置的匹配结果,代表了匹配的概率,选出其中概率最高的点,即为缺口匹配的位置:
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res) # 寻找最优匹配min_val,max_val,min_loc,max_loc分别为匹配的最小值、匹配的最大值、最小值的位置、最大值的位置。
至此,我们已经有了缺口的位置,其X轴坐标为:
X = max_loc[0]为了更直观地展示缺口的位置,我们将缺口用矩形框标注出来:
# 绘制方框
th, tw = tp_pic.shape[:2]
tl = max_loc # 左上角点的坐标
br = (tl[0]+tw,tl[1]+th) # 右下角点的坐标
cv2.rectangle(bg_img, tl, br, (0, 0, 255), 2) # 绘制矩形
cv2.imwrite('out.jpg', bg_img) # 保存在本地完整代码:
def identify_gap(bg,tp,out):
'''
bg: 背景图片
tp: 缺口图片
out:输出图片
'''
# 读取背景图片和缺口图片
bg_img = cv2.imread(bg) # 背景图片
tp_img = cv2.imread(tp) # 缺口图片
# 识别图片边缘
bg_edge = cv2.Canny(bg_img, 100, 200)
tp_edge = cv2.Canny(tp_img, 100, 200)
# 转换图片格式
bg_pic = cv2.cvtColor(bg_edge, cv2.COLOR_GRAY2RGB)
tp_pic = cv2.cvtColor(tp_edge, cv2.COLOR_GRAY2RGB)
# 缺口匹配
res = cv2.matchTemplate(bg_pic, tp_pic, cv2.TM_CCOEFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res) # 寻找最优匹配
# 绘制方框
th, tw = tp_pic.shape[:2]
tl = max_loc # 左上角点的坐标
br = (tl[0]+tw,tl[1]+th) # 右下角点的坐标
cv2.rectangle(bg_img, tl, br, (0, 0, 255), 2) # 绘制矩形
cv2.imwrite(out, bg_img) # 保存在本地
# 返回缺口的X坐标
return tl[0]