许多小伙伴们反应,在web自动化的过程中,常常会被登录的验证码给卡住,不知道怎样去经过验证码的验证。今日专门给咱们来聊聊验证码的问题,一般的情况下遇到验证码咱们能够都能够找开发去协助处理,封闭验证码,或许给一个全能的验证码!那么假如开发不供给协助的话,咱们自己有没有办法来处理这些验证码的问题呢?答案当然是有的,常见的验证码一般分为两类,一类是图文验证码,一类是滑动验证码!
关于图文辨认的验证码,之前现已出了相关的辨认处理方案,今日就不做过多的介绍了,有爱好的小伙伴能够私聊收取配套的视频材料。今日咱们主要来聊聊滑动验证码怎样去辨认破解。
滑动验证破解思路
关于滑动验证码破解的思路大体上来讲便是以下两个过程:
? 1、获取滑块滑动的间隔
? 2、模仿拖动滑块,经过验证。
? 听起来是比较简单,可是获取滑块滑动的间隔,大多数小伙伴没有思路,不知道怎样去获取。其实要获取下来也不难,关于这种滑动的验证码,滑块和缺口布景都是分别是一张独立的图片,咱们能够把这两张图片,下载下来凭借于图画辨认的技能,去辨认缺口在布景图中的方位,然后减去滑块当时所在方位,就能够得出需求滑动的间隔。这个时分许多小伙伴会想图画辨认技能我不会啊,不会没有关系,后边会给到咱们一个封装好的滑块辨认模块,只需你传入滑块和缺口布景图的元素节点就能核算出滑块的缺口方位。
事例解说
话不多说,咱们先来看一个事例(QQ空间登录),这边用到了一个我自己封装的滑动间隔辨认的模块slideVerfication,有需求的小伙伴能够私聊获取。qq空间登录事例完成过程如下:
? 1、创立一个driver目标,拜访qq登录页面
? 2、输入账号暗码
? 3、点击登录
? 4、模仿滑动验证
完成代码
"""============================Author:柠檬班-木森Time:2020/4/20 20:12E-mail:3247119728@qq.comCompany:湖南零檬信息技能有限公司============================"""import timefrom selenium import webdriverfrom slideVerfication import SlideVerificationCode# 1、创立一个driver目标,拜访qq登录页面browser = webdriver.Chrome()browser.get("")# 2、输入账号暗码# 2.0 点击切换到登录的iframebrowser.switch_to.frame('login_frame')# 2.1 点击账号暗码登录browser.find_element_by_id('switcher_plogin').click()# 2.2定位账号输入框,输入账号browser.find_element_by_id("u").send_keys("123292678")# 2.3定位暗码输入输入暗码browser.find_element_by_id("p").send_keys("PYTHON01")# 3、点击登录browser.find_element_by_id('login_button').click()time.sleep(3)# 4、模仿滑动验证# 4.1切换到滑动验证码的iframe中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')# 获取滑块图片的节点slideBlock_ele = browser.find_element_by_id('slideBlock')# 获取缺口布景图片节点slideBg = browser.find_element_by_id('slideBg')# 4.3核算滑动间隔sc = SlideVerificationCode(save_image=True)distance = sc.get_element_slide_distance(slideBlock_ele,slideBg)# 滑动间隔差错校对,滑动间隔*图片在网页上显现的缩放比-滑块相对的初始方位distance = distance*(280/680) - 22print("校对后的滑动间隔",distance)# 4.4、进行滑动sc.slide_verification(browser,slide_element,distance=100)
运转作用:
关于滑动验证码的辨认问题就这样处理了,那么接下来给咱们来讲讲封装的slideVerfication这个模块的辨认原理,其实关于这个模块图画辨认,也是凭借了第三方的图画处理模块来进行辨认的,python中有许多现成的用来处理图片的库,这边我运用的是opencv-python来进行辨认的。slideVerfication模块上面用到的两个办法的部分参阅代码如下:
def get_element_slide_distance(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 left
def 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()
? 关于滑动验证码辨认就给咱们共享到这儿了,上述处理方案也有对应的解说视频
