爬虫--破解滑动验证

一、cv2基本库函数

cv2.imread(filepath,flags):读入一张图像

  • filepath:要读入图片的完整路径
  • flags:读入图片的标志
    • cv2.IMREAD_COLOR:默认参数,读入一副彩色图片,忽略alpha通道
    • cv2.IMREAD_GRAYSCALE:读入灰度图片
    • cv2.IMREAD_UNCHANGED:顾名思义,读入完整图片,包括alpha通道

cv2.imshow(wname,img):显示图像

  • wname:显示图像窗口的名字
  • img:要显示的图像,窗口大小自动调整为图片大小

cv2.imwrite(file,img,num):保存一张图像

  • file:要保存的文件名
  • img:保存的图像
  • num:压缩的级别,默认为3

cv2.cvtColor(img,code) :图像颜色空间转换

  • img:要转换的图片
  • code:要转换颜色的数值
    • cv2.COLOR_RGB2GRAY:彩色图像转化为灰度图像
    • cv2.COLOR_GRAY2RGB:灰度图像转化为彩色图像
    • # cv2.COLOR_X2Y,其中X,Y = RGB, BGR, GRAY, HSV, YCrCb, XYZ, Lab, Luv, HLS

cv2.matchTemplate(img,templ,method):模板匹配

  • img:待搜索图像
  • templ:搜索模板,需和原图一样的数据类型且尺寸不能大于源图像
  • method:指定的匹配方法
    • CV_TM_SQDIFF----平方差匹配法(最好匹配0)
    • CV_TM_SQDIFF_NORMED----归一化平方差匹配法(最好匹配0)
    • CV_TM_CCORR----相关匹配法(最坏匹配0)
    • CV_TM_CCORR_NORMED----归一化相关匹配法(最坏匹配0)
    • CV_TM_CCOEFF----系数匹配法(最好匹配1)
    • CV_TM_CCOEFF_NORMED----化相关系数匹配法(最好匹配1)

cv2.minMaxLoc(res):矩阵的最小值,最大值,并得到最大值,最小值的索引

  • res:矩阵

cv2.rectangle(img,pt1,pt2,color[,thickness[,lineType[,shift]]]):计量图像的坐标轴

  • img:图片
  • pt1:矩形的左上角坐标
  • pt2:矩形的右下角坐标
  • color:矩形边框的颜色
  • thickness:矩形边框的厚度,如果为负值,如 CV_FILLED,则表示填充整个矩形
  • lineTpye:指定线形状
  • shift:点坐标中的小数位数,但是我感觉这个参数是在将坐标右移 shift 位一样

参考博客:https://blog.csdn.net/sinat_41104353/article/details/85171185

二、破解滑动验证

1.找出缺口距离

 def get_distance(self):
        """
        计算缺口的位置,由于缺口位置查找偶尔会出现找不准的现象,这里进行判断,
        :return: 距离和背景(模版)图
        """
        block_img_path = self.image_path + 'block.jpg'
        template_img_path = self.image_path + 'template.jpg'
        # 获取图片并灰度化
        block = cv2.imread(self.image_path + self.small_img, 0)
        template = cv2.imread(self.image_path + self.big_img, 0)
# 将二值化后的图片进行保存 cv2.imwrite(template_img_path, template) cv2.imwrite(block_img_path, block) block = cv2.imread(block_img_path) block = cv2.cvtColor(block, cv2.COLOR_BGR2GRAY) block = abs(255 - block) cv2.imwrite(block_img_path, block) block = cv2.imread(block_img_path) template = cv2.imread(template_img_path)
# 获取偏移量 result = cv2.matchTemplate(block, template, cv2.TM_CCOEFF_NORMED) min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result) y = max_loc[0] cv2.rectangle(template, max_loc, (max_loc[0] + 50, max_loc[1] + 50), (7, 249, 151), 2) return y, template

2.生成轨迹并滑动

 1 def get_track1(dis):
 2         """
 3         这个是用来模拟人为拖动滑块行为,快到缺口位置时,
 4         给定随机偏移量,最后在回归
 5         :return:
 6         """
 7         v = 0
 8         t = random.uniform(0.3, 0.8)
 9         x_offset = random.randint(15, 27)
10         dis = dis + x_offset
11         tracks = []
12         current = 0
13         mid = dis * 3 / 4
14         while current <= dis:
15             if current < mid:
16                 a = random.uniform(1, 24)
17             else:
18                 a = -(random.uniform(-1, 3))
19             v0 = v
20             t = random.uniform(0.05, 0.2)
21             s = v0 * t + 0.5 * a * (t ** 2)
22             current += s
23             tracks.append(round(s))
24             v = v0 + a * t
25         tracks.append(dis - sum(tracks))
26 
27         for x in range(x_offset):
28             tracks.append(-1)
29         return tracks

 

 1  def get_track2(distance):
 2         """
 3         根据偏移量和手动操作模拟计算移动轨迹
 4         :param distance: 偏移量
 5         :return: 移动轨迹
 6         """
 7         # 移动轨迹
 8         tracks = []
 9         # 当前位移
10         current = 0
11         # 减速阈值
12         mid = distance * 4 / 5
13         # 时间间隔
14         t = 0.2
15         # 初始速度
16         v = 0
17 
18         while current < distance:
19             if current < mid:
20                 a = random.uniform(2, 5)
21             else:
22                 a = -(random.uniform(12.5, 13.5))
23             v0 = v
24             v = v0 + a * t
25             x = v0 * t + 1 / 2 * a * t * t
26             current += x
27 
28             if 0.6 < current - distance < 1:
29                 x = x - 0.53
30                 tracks.append(round(x))
31 
32             elif 1 < current - distance < 1.5:
33                 x = x - 1.4
34                 tracks.append(round(x))
35             elif 1.5 < current - distance < 3:
36                 x = x - 1.8
37                 tracks.append(round(x))
38 
39             else:
40                 tracks.append(round(x))
41 
42         return tracks, 0

 

def get_track3(distance):
"""

:param distance:
:return:
"""
total_dis = 0
tracks = []
while True:
random_v = random.uniform(2, 4)
random_t = random.uniform(1.5, 2.5)
s = random_v * random_t

total_dis += round(s)
tracks.append(round(s))
if total_dis > distance:
offset = total_dis - distance
tracks.append(-offset)
break

return tracks, 0

 

    def get_track4(distance):
        """
        没有随机性
        :param distance:
        :return:
        """
        track = []
        current = 0
        mid = distance * 3 / 5.
        t = 0.2
        v = 0
        while current < distance:
            if current < mid:
                a = 2.
            else:
                a = -3.
            v0 = v
            v = v0 + a * t
            move = v0 * t + 1 / 2. * a * t * t
            current += move
            track.append(round(move))
        return track, 0

 

    def get_track5(distance):
        """
        本质来源于物理学中的加速度算距离: s = vt + 1/2 at^2
                                        v = v_0 + at
        在这里:总距离S= distance+20
                加速度:前3/5S加速度2,后半部分加速度是-3

        在上面的上增加随机回退
        """
        x_offset = random.randint(10, 30)
        distance += x_offset  # 先滑过一点,最后再反着滑动回来
        v = 0
        t = 0.2
        tracks = []

        current = 0
        mid = distance * 3 / 5
        while current < distance:
            if current < mid:
                a = random.randint(1, 3)
            else:
                a = int(random.uniform(-2, -4))

            s = v * t + 0.5 * a * (t ** 2)
            v = v + a * t
            current += s
            tracks.append(round(s))

        # 反着滑动到准确位置
        back_tracks = VerifySlider.random_num(random.randint(2, 5), -x_offset)
        print(tracks)
        print(back_tracks)
        return tracks, back_tracks

 

3.获取滑块

element = self.driver.find_element_by_css_selector(self.element_chunk_name)#获取滑块
ActionChains(self.driver).click_and_hold(on_element=element).perform()#鼠标点击到滑块位置
for track in tracks:#移动鼠标
     ActionChains(self.driver).move_by_offset(xoffset=track, yoffset=0).perform()
posted @ 2020-02-27 18:07  正在加载中…  阅读(362)  评论(0编辑  收藏  举报