使用selenium+OpenCV破解滑块验证码

文章目录

  • 1.滑块验证码思路
  • 2.工作要求
  • 3.准备工作
  • 4.爬取流程
  • 5.代码实现

1.滑块验证码思路

  • 滑动验证码一种是前端完成的,会有一张原图和一张缺口图,那么可以通过像素对比来完成
  • 另一种是只要缺口图和滑块图,可以通过OpenCV来进行滑块匹配缺口图。

2.工作要求

  • 爬取网站:https://dun.163.com/trial/sense
  • 进入网站点击可疑用户-滑动拼图验证码,然后破解此滑动验证码

使用selenium+OpenCV破解滑块验证码_第1张图片

使用selenium+OpenCV破解滑块验证码_第2张图片

3.准备工作

①selenium+phantomjs+chorm的安装

查看博客:selenium+chorm安装

②requests的安装

pip install requests

③numpy的安装

pip install numpy

④OpenCV的安装

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple/ opencv-python

如果在使用过程中,cv2没有代码提示,寻找到cv2目录下的init文件,将内容替换为:

使用selenium+OpenCV破解滑块验证码_第3张图片

4.爬取流程

寻找此点击块儿的xpath

使用selenium+OpenCV破解滑块验证码_第4张图片

用selenium+chorm–>依次点击可疑用户-滑块拼图–>点击 点击完成验证按钮

使用selenium+OpenCV破解滑块验证码_第5张图片
,然后加载出图片
使用selenium+OpenCV破解滑块验证码_第6张图片

此滑块验证码存入两个图片,一个验证块,一个缺失块背景,因此需要通过requests下载两张图片

使用selenium+OpenCV破解滑块验证码_第7张图片

下载完后,开始处理两张图片,使用OpenCV,先将图片灰度处理,可以提高处理速度。

使用selenium+OpenCV破解滑块验证码_第8张图片

使用selenium+OpenCV破解滑块验证码_第9张图片

灰度处理完后会发现,滑块图多出一些黑色,因为下载过程中就有了多余的块,灰度后会变为黑色,因此我们将亮的块保留,黑色部分切除
使用selenium+OpenCV破解滑块验证码_第10张图片

使用算法,对滑块和背景图进行匹配

在这里插入图片描述

得到横纵坐标位置后,我们该验证码只需要移动横坐标,但是在OpenCV中我们横向移动相当于OpenCV的纵向移动,因此我们首先去寻找滑动块的标签,然后由上述算法得到x,y,将横线移动y的距离

使用selenium+OpenCV破解滑块验证码_第11张图片

寻找到此块,我们需要用selenium实现 :抓住—>按钮不放,直到移动完x距离再放开
使用selenium+OpenCV破解滑块验证码_第12张图片

看到上图图片,发现原图比例和现在的图比例不同,即网页中按比例缩小了图片,但是此图比例太小,略微不计,也可以通过,但是不是一定通过,可能存在误差。
使用selenium+OpenCV破解滑块验证码_第13张图片

5.代码实现

from selenium.webdriver import Chrome
from selenium.webdriver.common.action_chains import ActionChains
import time
import requests
import cv2 as cv
import numpy as np

# -------------------------------------爬取滑块验证码中的两个图片
# 创建浏览器
web = Chrome()

# 获取网站
web.get('https://dun.163.com/trial/sense')

# 寻找可疑用户-滑动拼图按钮,点击,由于加载较慢,需要设置一两秒的等待
web.find_element_by_xpath('/html/body/main/div[1]/div/div[2]/div[2]/ul/li[2]').click()
time.sleep(1.5)

# 寻找点击完成验证按钮块,点击,由于加载较慢,需要设置一两秒的等待
web.find_element_by_xpath('/html/body/main/div[1]/div/div[2]/div[2]/div[1]/div[2]/div[1]/div/div[2]/div[3]/div/div/div[1]').click()
time.sleep(2)

# 寻找滑块图片和缺失背景图片的url地址
bg_img_src=web.find_element_by_xpath('/html/body/main/div[1]/div/div[2]/div[2]/div[1]/div[2]/div[1]/div/div[2]/div[3]/div/div/div[2]/div/div/div[1]/div/div[1]/img[1]').get_attribute('src')

front_img_src=web.find_element_by_xpath('/html/body/main/div[1]/div/div[2]/div[2]/div[1]/div[2]/div[1]/div/div[2]/div[3]/div/div/div[2]/div/div/div[1]/div/div[1]/img[2]').get_attribute('src')

# 将这两个图片根据url,下载到本地
with open('bg.jpg','wb') as f:
    f.write(requests.get(bg_img_src).content)
with open('front.jpg','wb') as f:
    f.write(requests.get(front_img_src).content)

# ----------------------------------------处理图片,寻找豁口
# 读取图片
bg = cv.imread('bg.jpg')
front = cv.imread('front.jpg')

# 灰度处理,是为了提高我们的效率,类似于降维打击
bg = cv.cvtColor(bg, cv.COLOR_BGR2GRAY)  # 将blue,green,red转为gray
front = cv.cvtColor(front, cv.COLOR_BGR2GRAY)  # 将blue,green,red转为gray

# 对滑块处理,我们下载出来滑块图片,发现上下多了一对空白,经过灰度会将此空白变成黑色,如果用此图片匹配背景会有问题,因此需要切除
front = front[front.any(1)]  # 1是要灰度后边比较亮的,黑色就是暗的数字0,因此这样做会将小块儿留下来

# 用滑块匹配背景图
# cv.TM_CCOEFF_NORMED算法,匹配精度最高,时间最慢,会将滑块每个像素点与背景图像素对比,返回一个每个像素点匹配相似度的矩阵,寻找相似度最大的
result = cv.matchTemplate(bg, front, cv.TM_CCOEFF_NORMED)
yiwei_max_loc = np.argmax(result)  # 返回矩阵的最大一维位置,但是我们需要二维的位置
x, y = np.unravel_index(yiwei_max_loc, result.shape)  # 会将一维的位置逆向根据二维的形状,返回位置横纵坐标

# 我们这个滑块验证码只需要移动横坐标
# 寻找移动的滑块
div=web.find_element_by_xpath('/html/body/main/div[1]/div/div[2]/div[2]/div[1]/div[2]/div[1]/div/div[2]/div[3]/div/div/div[2]/div/div/div[2]/div[2]')

# 引入动作链发生在哪个浏览器,drag_and_drop_by_offset方法是抓住块移动多少再放下
# 但是OpenCV比较奇葩,纵坐标和横坐标相反,在我们人的横坐标移动是OpenCV的纵坐标移动
# 如果浏览器没动静,可能我们下载得图片和原来的网页图片大小比例不同,需要自己算比例,然后对移动值计算
# 当然此方法不一定100%可以过去
ActionChains(web).drag_and_drop_by_offset(div,xoffset=y,yoffset=0).perform()

学习链接:https://www.bilibili.com/video/BV1zJ41187i8?t=4170

你可能感兴趣的:(python爬虫)