很多朋友反馈,在web自动化的过程中,经常被登录的验证码卡住,不知道验证码怎么过。今天,我想和你谈谈验证码。一般情况下可以找开发商帮忙解决,关闭验证码,或者给个通用验证码!那么如果开发没有帮助,我们有什么办法处理这些验证码呢?当然,答案是肯定的。常见的验证码一般分为两类,一类是图形验证码,一类是滑动验证码!
关于图形识别的验证码,之前已经开发了相关的识别解决方案,今天就不多介绍了。有兴趣的朋友可以私聊获取配套视频资料。今天主要讲一下如何识别和破解滑动验证码。
滑动验证和破解的思路一般是以下两个步骤:
1.获取滑块的滑动距离。
2.模拟拖动滑块,通过验证。
听起来很简单,但是要得到滑块的滑动距离,大部分朋友都没有概念,不知道怎么得到。其实并不难得到。关于这个滑动验证码,滑块和缺口的背景是分开的图像。我们可以下载这两幅图像,借助图像识别技术,识别出背景图像中缺口的位置,然后减去滑块的当前位置,得到要滑动的距离。这时候很多朋友会觉得我认不出图像技术。没有也没关系。稍后我们会给你一个打包的滑块识别模块。只要传入滑块和凹口背景图片的元素节点,就可以计算出滑块的凹口位置。
没有太多可以解释的情况。我们先来看一个案例(QQ空间登录)。这里我用过一个滑动距离识别模块,slideVerfication,自己打包的。有需要的朋友可以私聊获取。qq空间登录案例的实现步骤如下:
1.创建一个驱动程序对象并访问qq登录页面。
2.输入帐户密码。
3.单击登录。
4.模拟滑动验证
实现代码 =====================作者:柠檬类-木森时间:2020/4/0 20:12 e-邮箱:3247119728 @ qq.com公司3360湖南零度柠檬信息技术有限公司Ltd.====================== 从Selenium导入WebDriver从Citation导入slideverificationcode # 1、创建驱动程序对象,访问qq登录页面browser=web driver . chrome()browser . get( https://qzone . QQ.com/)# 2、输入账号密码# 2.0点击切换到iframe browser . switch _ to . frame( log in _ frame )# 2.1点击账号密码登录browser.find _ element _ by _ id() 点击()# 2.2定位账号输入框,输入账号browser.find _ element _ by _ id (U )。Send _ keys (123292678) # 2.3输入位置密码browser.find _ element _ by _ id (P )。Send _ keys (Python01) # 3,点击浏览器。find _ element _ by _ id(登录_按钮)。单击()时间。睡眠(三)# 4, 模拟滑动验证# 4.1切换到TCAPTCHA=browser . find _ element _ by _ id( TCAPTCHA _ iframe )browser . Switch _ to . frame(TCAPTCHA)# 4.2获取滑动相关元素#选择节点slide _ element=browser . find _ element _ by _ id( TCAPTCHA _ drag _ thumb )#节点slide block _ ele=browser . find _ element _ by _ id( slide block )# 获取缺口背景图片节点slide BG=browser . find _ element _ by _ id( slide BG )# 4.3计算滑动距离sc=slide verification code(save _ image=true)Distance=sc . get _ element _ slide _ Distance(slide block _ ele,slide bg) #滑动距离的误差修正,滑动距离*图片在网页上显示的缩放比例-滑块的初始位置相对距离=distance * (280/680)-22print(修正的滑动距离),distance)# 4.4,滑动sc。 slide _ verification (browser,slide _ element,Distance=100)运行效果:这样就解决了滑动验证码的识别问题。然后,我们来说说封装的slideVerfication模块的识别原理。其实这个模块的图像识别也是借助第三方图像处理模块进行的。python中有很多现成的处理图片的库,这里我用opencv-python进行识别。上面在slideVerfication模块中使用的两种方法的一些参考代码如下:
def get _ element _ slide _ distanc
e(self, slider_ele, background_ele, correct=0): """ 根据传入滑块,和背景的节点,计算滑块的距离 该方法只能计算 滑块和背景图都是一张完整图片的场景, 如果背景图是通过多张小图拼接起来的背景图, 该方法不适用,请使用get_image_slide_distance这个方法 :param slider_ele: 滑块图片的节点 :type slider_ele: WebElement :param background_ele: 背景图的节点 :type background_ele:WebElement :param correct:滑块缺口截图的修正值,默认为0,调试截图是否正确的情况下才会用 :type: int :return: 背景图缺口位置的X轴坐标位置(缺口图片左边界位置) """ # 获取验证码的图片 slider_url = slider_ele.get_attribute("src") background_url = background_ele.get_attribute("src") # 下载验证码背景图,滑动图片 slider = "slider.jpg" background = "background.jpg" self.onload_save_img(slider_url, slider) self.onload_save_img(background_url, background) # 读取进行色度图片,转换为numpy中的数组类型数据, slider_pic = cv2.imread(slider, 0) background_pic = cv2.imread(background, 0) # 获取缺口图数组的形状 -->缺口图的宽和高 width, height = slider_pic.shape[::-1] # 将处理之后的图片另存 slider01 = "slider01.jpg" background_01 = "background01.jpg" cv2.imwrite(background_01, background_pic) cv2.imwrite(slider01, slider_pic) # 读取另存的滑块图 slider_pic = cv2.imread(slider01) # 进行色彩转换 slider_pic = cv2.cvtColor(slider_pic, cv2.COLOR_BGR2GRAY) # 获取色差的绝对值 slider_pic = abs(255 - slider_pic) # 保存图片 cv2.imwrite(slider01, slider_pic) # 读取滑块 slider_pic = cv2.imread(slider01) # 读取背景图 background_pic = cv2.imread(background_01) # 比较两张图的重叠区域 result = cv2.matchTemplate(slider_pic, background_pic, cv2.TM_CCOEFF_NORMED) # 获取图片的缺口位置 top, left = np.unravel_index(result.argmax(), result.shape) # 背景图中的图片缺口坐标位置 print("当前滑块的缺口位置:", (left, top, left + width, top + height)) return leftdef slide_verification(self, driver, slide_element, distance): """ 滑动滑块进行验证 :param driver: driver对象 :type driver:webdriver.Chrome :param slide_element: 滑块的元组 :type slider_ele: WebElement :param distance: 滑动的距离 :type: int :return: """ # 获取滑动前页面的url地址 start_url = driver.current_url print("需要滑动的距离为:", distance) # 根据滑动距离生成滑动轨迹 locus = self.get_slide_locus(distance) print("生成的滑动轨迹为:{},轨迹的距离之和为{}".format(locus, distance)) # 按下鼠标左键 ActionChains(driver).click_and_hold(slide_element).perform() time.sleep(0.5) # 遍历轨迹进行滑动 for loc in locus: time.sleep(0.01) ActionChains(driver).move_by_offset(loc, random.randint(-5, 5)).perform() ActionChains(driver).context_click(slide_element) # 释放鼠标 ActionChains(driver).release(on_element=slide_element).perform()
关于滑动验证码识别就给大家分享到这里了,上述解决方案也有对应的讲解视频
相关文章