赞
踩
网上的的滑块解锁图形,五花八门,十个里面九个瘫,步步都是坑
目标很简单,就是把滑块放进缺少的图片中
也就是说,访问第一次之后,直接F12算出面积,直接把长度放入代码中即可
这种的话,比较第一种较难点,思路很简单,就是设置一个长度,不断的递增就可以了,比如第一个图可能要求拉15cm也可能是拉33cm才可以,但是我就从3cm开始测试就可以了,3cm不行6cm,6cm不行9cm,反正没刷新图片15cm永远都在那里等着我
这就是今天的反爬虫机制最高的境界,时时刻刻变位置,前两种的思路都不可以用了,只能计算出长度进行拉取,这也就是这篇博客要讲解的重头戏
这是大佬地址,我看了他的博客,只感觉在纸上谈兵,还对骂了一番
附上大佬的代码
def download_yzm(self):
js = '''
return document.getElementById('puzzle-lost').toDataURL()
'''
base64str = self.driver.execute_script(js)
resultstr = base64str.strip("data:image/png;base64")
resultstr = resultstr[1:]
imagedata = base64.b64decode(resultstr)
file = open('./bg.png', "wb")
file.write(imagedata)
file.close()
首先,不看别的,只看到js里面有return 我就知道会报错了,我很纳闷他试了没
在console里面执行js不知道哪个前端加过return才会有数据显示??
他没有实践,所以没有考虑很多问题,比如canvas下载图片地址toDataURL是存在跨域问题的,又比如每次图片滑动的距离并不是写死的,背景图会时时刻刻变化的,所以写代码还是多动手比较好
#移动前获取滑块那部分页面上的图片用selenium截图的形式 driver.find_elements_by_xpath('//*[@class="yidun_bg-img"]')[1].screenshot('0.png') bg_act = cv.imread('0.png') bg_act_height, bg_act_width = bg_act.shape[0],bg_act.shape[1] bg = cv.imread('bg_img.png') bg_height, bg_width = bg.shape[0],bg.shape[1] block = cv.imread('img.png', -1) scale = bg_act_height * 1.0 / bg_height scale1 = bg_act_width * 1.0 / bg_width block_act = cv.resize(block, (0,0), fx = scale, fy=scale) print('scale: ', scale, scale1) x1,x2 =get_image_deviation(bg, block) x1 = int(x1*scale) print("x1x2=", x1, x2) #部分代码 ActionChains(滑块元素).move_by_offset(xoffset= 移动上面生成的距离, yoffset=0).perform() #第一次移动后二次识别部分代码 driver.find_elements_by_xpath('//*[@class="yidun_bg-img"]')[1].screenshot('bg1.png') bg_act1 = cv.imread('bg1.png') x3,x4=get_image_deviation(bg_act1, block_act) print("x3x4=", x3, x4) time.sleep(5) ActionChains(driver).move_by_offset(xoffset= x1-x3, yoffset=0).perform()
两次图片匹配,识别率来完成,我呵呵了,这个鬼才也算有想法的,不断匹配识别来达到目的,但是电脑截图下来的图片你存哪里了,不保存放内存中自己消化了?图片不变化的话,或许你这种方法有点用
这个就6的狠了,人为的进行打开网页点击保存图片,这里保存图片参看我另外一篇博客,网上很多文章也不行,自己摸索出来的最终解决方案
Python selenium自动化脚本右键保存图片_一蓑烟雨任平生
保存并不算很难,也就耗用了我两小时研究,网上天花乱坠,没营养的代码一堆一堆的,走了很多弯路,这里保存之后命名图片名称是一个难点,毕竟锁定IP并不是锁定一次滑动验证码就可以了,会频繁的锁定,所以要频繁的滑动解锁,这里重点讲解下selenium的删除和命名文件
直接上代码啊
def rnameFile(): # 查找文件 path = "E:\\xiazai"#这是你浏览器下载地址 # os.listdir()方法,列出来所有文件 # 返回path指定的文件夹包含的文件或文件夹的名字的列表 files = os.listdir(path) # 主逻辑 # 删除该文件 os.remove("E:\\xiazai\\bg.png") print('删除北京成功') # 删除该文件 os.remove("E:\\xiazai\\huakuai.png") print('删除滑块图片成功') # 对于批量的操作,使用FOR循环 for f in files: # 调试代码的方法:关键地方打上print语句,判断这一步是不是执行成功 print(f) if "1" in f and f.endswith(".png"): # 这里应该打印下载(1).png print("原来的文件名字是:{}".format(f)) # 找到老的文件所在的位置 old_file = os.path.join(path, f) print("old_file is {}".format(old_file)) # 指定新文件的位置,如果没有使用这个方法,则新文件名生成在本项目的目录中 new_file = os.path.join(path, "bg.png") print("File will be renamed as:{}".format(new_file)) os.rename(old_file, new_file) print("修改后的文件名是:{}".format(f)) elif "下载" in f and f.endswith(".png"): # 这里应该打印下载.png print("原来的文件名字是:{}".format(f)) # 找到老的文件所在的位置 old_file = os.path.join(path, f) print("old_file is {}".format(old_file)) # 指定新文件的位置,如果没有使用这个方法,则新文件名生成在本项目的目录中 new_file = os.path.join(path, "huakuai.png") print("File will be renamed as:{}".format(new_file)) os.rename(old_file, new_file) print("修改后的文件名是:{}".format(f)) if __name__ == '__main__': rnameFile()
#.缺口图片匹配缺口所在图片那一行图片可以提高他识别率 def get_image_deviation(): ##读取滑块图 block = cv.imread("img.png", -1) #完整图片有个缺口 backimg = cv.imread("bg_img.png") #缺口图片 # block = cv.resize(block, (240, 480)) # backimg = cv.resize(block, (240, 480)) ##灰度化 gray_backimg = cv.cvtColor(backimg, cv.COLOR_RGB2GRAY) blockWidth, blockHeight = block.shape[1], block.shape[0] ##识别滑块图前景 ###由于滑块图为带透明的png,可根据透明通道来判断前景位置 ##识别物体框,生成blockmask left = blockWidth right = 0 top = blockHeight bottom = 0 for i in range(0, blockHeight): for j in range(0, blockWidth): if block[i, j, 3] > 0: if j <= left: left = j if j >= right: right = j if i <= top: top = i if i >= bottom: bottom = i blockBox = block[top:bottom, left:right] blockBox_width, blockBox_height = blockBox.shape[1], blockBox.shape[0] print(blockBox_width) blockMask = np.zeros([blockBox_height, blockBox_width], np.uint8) for i in range(0, blockBox_height): for j in range(0, blockBox_width): if blockBox[i, j, 3] > 0: blockMask[i, j] = 255 blockBox = cv.cvtColor(blockBox, cv.COLOR_RGBA2GRAY) ##由于边界点存在光照影响,为了避免边界点对匹配的影响,进行腐蚀操作 kernel = np.ones((3, 3), np.uint8) blockMask = cv.erode(blockMask, kernel, iterations=1).astype(np.float32) backgroundROI = gray_backimg[top:bottom, :] ##将backgroundROI、blockBox都转化成float型 blockBox = (blockBox * 1.0).astype(np.float32) backgroundROI = (backgroundROI * 1.0).astype(np.float32) ##使用cv的 res = cv.matchTemplate(backgroundROI, blockBox, cv.TM_CCORR_NORMED, mask=blockMask) loc = cv.minMaxLoc(res) print("loc==", loc[3][0]) locs = (loc[3][0]) return locs
上面代码走不通,这就是没营养的东西
# -*- coding: utf-8 -*- """ @Time : ${DATE} ${TIME} @Auth : 一蓑烟雨任平生 @File :${NAME}.py @IDE :${PRODUCT_NAME} @Motto:ABC(Always Be Coding) """ import cv2 def FindPic(bg, huakuai): """ 找出图像中最佳匹配位置 :param bg: 你下载的背景图 :param huakuai: 滑块的图片 :return: 滑动距离 """ target_rgb = cv2.imread(bg) target_gray = cv2.cvtColor(target_rgb, cv2.COLOR_BGR2GRAY) template_rgb = cv2.imread(huakuai, 0) res = cv2.matchTemplate(target_gray, template_rgb, cv2.TM_CCOEFF_NORMED) value = cv2.minMaxLoc(res) return str(value).split('(')[3].split(',')[0]
## 计算距离 def FindPic(bg, huakuai): ''' bg: 背景图片 tp: 缺口图片 ''' # 读取背景图片和缺口图片 bg_img = cv2.imread(bg) # 背景图片 tp_img = cv2.imread(huakuai) # 缺口图片 # 识别图片边缘 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) # 绘制矩形 print(tl[0]) # 返回缺口的X坐标 return tl[0]
12行代码搞完不香吗?非要搞100多行代码吓唬我啊
这里只要学着人为的开始时候加速,然后减速放进去就OK了
def get_tracks(distance, rate=0.6, t=0.2, v=0): """ 将distance分割成小段的距离 :param distance: 总距离 :param rate: 加速减速的临界比例 :param a1: 加速度 :param a2: 减速度 :param t: 单位时间 :param t: 初始速度 :return: 小段的距离集合 """ tracks = [] # 加速减速的临界值 mid = rate * distance # 当前位移 s = 0 # 循环 while s < distance: # 初始速度 v0 = v if s < mid: a = 40 else: a = -3 # 计算当前t时间段走的距离 s0 = v0 * t + 0.5 * a * t * t # 计算当前速度 v = v0 + a * t # 四舍五入距离,因为像素没有小数 tracks.append(round(s0)) # 计算当前距离 s += s0 return tracks
这里就不在列举网上那些闪电滑块,蜗牛滑块的代码了,我累了
我个人原因太懒,不喜欢写代码一大堆一大堆的,只要能实现效果,越少越好,一行能解决的事情绝对不用10行,这就是我,懒人一个,烂人一个
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。