> 文档中心 > 不想用selenium处理滑块验证码?教你用cv2解决

不想用selenium处理滑块验证码?教你用cv2解决

cv2解决滑块验证码验证

  • opencv-python安装
  • 案例场景
  • cv2实战

opencv-python安装

虽然cv2是直接通过导入cv2包使用,但是它不是通过import cv2安装,需要通过pip install opencv-python安装,直接pip安装可能会比较慢,可以使用pip install opencv-python -i https://pypi.tuna.tsinghua.edu.cn/simple安装

案例场景

在这里插入图片描述
在这里插入图片描述
当点击滑块时,会显示缺口背景图和方块,将方块移动到背景图缺口处就能实现验证,我们可以看看验证通过整个过程的请求包来判断它的验证逻辑
在这里插入图片描述
当我们点击滑块时,会去请求方块和背景图,当我们滑动并停止滑动滑块后,会发起一个验证请求,推测这个请求会把我们的动作传给后端验证,而我们的动作直接产生的就是坐标的变化,一般验证码验证会根据两种方式验证,坐标参数验证滑动轨迹验证码坐标参数验证是传递一个滑块停止后的坐标,而滑动轨迹验证码是传递一个坐标数组,记录滑块整个滑动周期变化的坐标。

我们查看异步请求验证这个包,看看它传递的参数便可以知道属于哪种验证逻辑
在这里插入图片描述
观察参数可以确定它传递的是滑块移动停止时的坐标,那怎么拿到这个坐标呢,dragleft我们假定是方块左侧坐标的距离,dragright我们假定是方块右侧坐标的距离,然后模拟一下查看style样式中left的变化。
在这里插入图片描述
多次观察可以确定,这个left便是dragleft的值,而dragrightdragleft要大32,这样我们只要知道dragleft的值便能确定dragright了。

cv2实战

使用cv2计算图片差异位置的坐标,我们需要拿到背景图片和方块图片,通过对比背景图片和方块图片之间的联系与差异从而定义差异的坐标。

cv2识别代码

# -*- coding: utf-8 -*-from PIL import Imagefrom io import BytesIOimport numpy as npimport cv2def identify_gap(bg, tp):    """    :param bg: 背景图片    :param tp: 缺口图片    :return int    """    # 读取背景图片和缺口图片    bg_img = get_cv2_img(bg)  # 背景图片    tp_img = get_cv2_img(tp)  # 缺口图片    if type(bg_img) == str or type(tp_img) == str: print('图片格式存在问题,无法用cv2读取!') return    # 识别图片边缘    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)    print(min_val, max_val, min_loc, max_loc)    # 返回缺口的X坐标    return max_loc[0]def get_cv2_img(img_object):    if type(img_object) == str: cv_img = cv2.imread(img_object)    elif type(img_object) == bytes: image_data = BytesIO(img_object) img = Image.open(image_data) cv_img = np.asarray(img)    else: cv_img = None    return cv_imgif __name__ == '__main__':    print(identify_gap('背景图本地路径', '方块本地路径'))    print(identify_gap('背景图二进制流', '方块二进制流'))

测试识别结果

# -*- coding: utf-8 -*-import requestsfrom sxSpider.check_open_cv.cv2_gap import identify_gapheader = {    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',    'Accept-Encoding': 'gzip, deflate, br',    'Cookie': 'lnReGnsFlag=0; tbbysb=N; tbzbsy=N; LESB_SESSION=ZF9tq3-Avn6LnFE80mstxwI3QTwoHZdyPrz_FWuwwpPu_As9a2fy!46501968',    'Host': 'etax.ningxia.chinatax.gov.cn',    'Upgrade-Insecure-Requests': '1',    'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36',}before_img_url = 'https://etax.ningxia.chinatax.gov.cn/download.sword?ctrl=CheckcodeCtrl_initBgPic&0.1601673354750519&bgPicPath=/wsbs/images/bg4_style2.jpg&id=dragCheckCode'after_img_url = 'https://etax.ningxia.chinatax.gov.cn/download.sword?ctrl=CheckcodeCtrl_initcutPic&0.14661519005791934&bgPicPath=/wsbs/images/bg4_style2.jpg&id=dragCheckCode'before_img_resp = requests.get(before_img_url, headers=header)before_img = before_img_resp.contentwith open('image/before.png', 'wb') as fb:    fb.write(before_img_resp.content)after_img_resp = requests.get(after_img_url, headers=header)after_img = after_img_resp.contentwith open('image/after.png', 'wb') as fb:    fb.write(after_img_resp.content)drag_left = identify_gap(before_img, after_img)drag_right = drag_left + 32print(drag_left, drag_right)

如果想看看识别的到底对不对,可以圈出识别位置

# 绘制方框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('存储路径', bg_img)  # 保存在本地

在这里插入图片描述
ok,分享就到这里了!

唱吧电脑版