当前位置: 首页 > Web前端 > HTML

验证码识别

时间:2023-04-02 16:15:17 HTML

写在前面现在很多网站为了防止爬虫采取了各种措施,其中之一就是使用验证码。当我们访问一个网页时,首先要通过验证码才能访问该页面。下面我们就说一下这两种验证码的识别方法和一些思路。当然,我们也可以直接使用付费打码平台,这样可以增加识别的准确率,毕竟我们是付费的。哈哈!PIL库其实验证码识别归根结底就是对各种图片的识别和操作。python中有很多图像处理库,PIL就是其中之一。所以在处理验证码识别之前,首先要了解PIL库和tesserocr。下面附上它的API源码地址,以及对应的学习博客。源码地址:https://pillow-cn.readthedocs.io/zh_CN/latest/reference/index.html参考博客:https://blog.csdn.net/louishhao/article/details/69879981下面开始验证码认可之道。图文验证码以知网为例:首先我们先获取上图中绿线标记的验证码,下载到本地工程文件中,然后编写如下代码:importtesserocrfromPILimportImageimage=Image.open('image.png')res=tesserocr.image_to_text(image)print(res)#F8BS输出结果为:F8BS,但实际图片为F8B8。这是因为验证码中的多余线条干扰了图片的识别。在这种情况下,需要进行额外的处理,例如灰度转换、二值化等。当然,在实际处理中并非如此。一般我们会先对模糊图像进行灰度化,然后设置二值化的阈值。实际处理如下:importtesserocrfromPILimportImageimage=Image.open('code.jpg')#创建图像对象image=image.convert('L')threshold=150#指定二值化阈值table=[]fori在范围(256)内:如果我<阈值:table.append(0)否则:table.append(1)image=image.point(table,'1')image.show()res=tesserocr.image_to_text(image)print(res)输出结果:F8B8识别时,先设置二值化阈值threshold,适当调试,直到能正常识别图片。滑动验证码流程分析:滑动验证码的主要验证方式是拖动滑块和组合图片;如果图片完全组合,则验证成功,即表单提交成功,否则需要重新验证。如图所示:下面,我们以极度验证的验证码为例,对识别方法进行说明。因为极速验证码拖验证码后会生成一个加密的表单提交到后台,所以为了避免麻烦,我们直接使用selenium模拟浏览器行为来完成验证。登录网址:Geetest官网目标网址:https://account.geetest.com/l...首先我们发现在登录界面有一个智能按钮。一般来说,输入邮箱地址后,点击按钮会弹出滑动验证窗口,然后我们拖动验证码完成图片拼接,完成验证。因此,滑块的验证识别需要完成以下步骤:模拟点击验证按钮识别滑块的间隙位置模拟拖动滑块如何实现以上步骤?我们首先需要分解任务。似乎只有三个主要步骤。其实这里面有很多坑,后面会说明。第一步,输入账号,获取智能按钮,使用selenium模拟点击,获取有缺口的图片。第二步,获取上图刘海中的全貌。这里需要注意一件事。一般情况下,我们在网页源代码中是找不到完整图片的,因为它是隐藏的,必须执行javascript语句才能显示完整图片。我们把display参数改成block,opacity参数改成1,然后截图得到完整的验证码图片。第三步,比较两幅图像的所有RGB像素,得到间隙的位置。第四步,模拟人的拖动习惯。这里也有陷阱。极速验证码增加了机器轨迹识别,滑块匀速或随机移动都无法通过验证。因此,我们把需要拖动的总位移分成一条小轨迹,先匀加速拖动,再匀减速拖动。第五步,按照指定轨迹拖动,完成校验。第六步,完成账号登录。流程分析完了,下面我们来写代码试试看:首先,对整个代码的逻辑做一个大概的概述。defmain():"""主函数"""#获取带间隙的验证码图片image1,传入参数后缀为:.pngimage1=get_unFull_captcha('unfull_captcha.png')#print(image1.load()[12,25])#获取全验证码图片image2image2=get_full_captcha('full_captcha.png')#比较以上图片像素,获取空位,获取偏移distance=get_quekou_distance(image1,image2)print('间隙偏移Shift:',distance)#获取滑块的移动轨迹track=get_track(distance)#模拟人体行为,拖动滑块,完成验证slider=get_slider()move(slider,track)成功=wait.until(EC.text_to_be_present_in_element((By.CLASS_NAME,'geetest_success_radar_tip_content'),'验证成功'))print(success)ifsuccess:login()else:main()接下来完成要实现的功能在main函数中一一上来。代码示例:通过上面的代码,我们得到了完整的验证码和有缺口的验证码。Gapimage:defget_unFull_captcha(name):"""获取一个有空隙的验证码图片:return:unfullcaptcha"""top,bottom,left,right=get_captcha_position('geetest_canvas_slice')print('Captcha1position:',top,bottom,left,right)screenshot=get_screenshot()unfull_captcha=screenshot.crop((left,top,right,bottom))#根据图片位置裁剪unfull_captcha.save(name)#这里传入的name应该是xxx。PNGnamereturnunfull_captchafullpicture:defget_full_captcha(name):"""获取完整captchapicture:return:full_captcha"""#这里需要执行JavaScript脚本获取完整图片的截图show_Full_img1="document.getElementsByClassName('geetest_canvas_fullbg')[0].style.display='block'"browser.execute_script(show_Full_img1)show_Full_img2="document.getElementsByClassName('geetest_canvas_fullbg')[0].style.opacity=1"browser.execute_script(show_Full_img2)#等待完整图像加载time.sleep(2)top,bottom,left,right=get_captcha_position('geetest_canvas_fullbg')print('Captcha2position:',top,bottom,left,right)screenshot=get_screenshot()full_captcha=screenshot.crop((left,top,right,bottom))#同上full_captcha.save(name)returnfull_captcha这里调试的时候遇到了一个坑,因为在chrome中,location方法没有scroll,直接返回相对于整个html的坐标。我的电脑是15.6英寸。显示设置上布局的缩放尺寸放大到1.25倍,导致location返回的坐标和验证码的坐标有误差。修改layout为100%,解决。向上。下面通过图片对比,找出缺口的位置。这里我们需要遍历图像的坐标点,获取像素点的RGB数据。代码示例defget_quekou_distance(image1,image2):"""比较像素得到间隙位置:paramimage1:gapimage:paramimage2:completeimage:return:间隙的偏移距离"""#间隙在右侧slider,设置遍历初始横坐标left为59left=60#pixelcontrastthreshold=60foriinrange(left,image2.size[0]):forjinrange(image2.size[1]):rgb1=image1.load()[i,j]rgb2=image2.load()[i,j]res1=abs(rgb2[0]-rgb1[0])res2=abs(rgb2[1]-rgb1[1])res3=abs(rgb2[2]-rgb1[2])ifnot(res1