爬虫--破解滑动验证
一、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()