相信大家在日常划水,培训,工作中都遇到这样的问题,验证码怎么处理?也有一些面试官会这么问。
这里大致的说说,最常见的处理方式。
1、万能验证码:所谓的万能验证码也就是找开发固定一个验证码,比如abcd,12cd这种,每次打开固定不变,永远都是同一个验证码。或者说是,不管你输入什么验证码都是正确的,代码不对验证码进行校验。
2、注销验证码:这里呢就是直接找开发,经过协商,开发把验证码这一块代码注释掉。这里跟上述所说的其实类似。
3、cookie登录:了解过接口的都知道,登录账号密码过程中,其实是一次发起请求的过程,有发起请求对应的会有返回响应。那么cookie就在这里面了。我们可以通过循环里面的内容,绕过登录这个环节,直接进入登录后的界面。后续会出文。
4、最后一种,那当然就是本篇要介绍的,纯技术搞定。图像识别。本文介绍两种。第一种pytesseract+PIL,第二种就是一个库,我也是最近才发现的:ddddocr。我理解的就是懂得都懂orc。玩笑开完,先来简单看看例子。
pytesseract+PIL
这种需要用到工具Tesseract-OCR,下载地址:https://digi.bib.uni-mannheim.de/tesseract/
还需要配置环境变量:
第一,在系统变量path中添加:E:\picture_dev\Tesseract-OCR,这里是你安装的路径,需要根据自己的实际安装路径更改。
第二:系统变量path新建一个环境,并且将你下载解压的Tesseract-OCR路径写进去,如下图
这两下载完了,接下来就是:
pip install Pillow
pip install pytesseract
下载工具对应所需要的包啦。下载完后试试如下两个命令:
接下来我们可以开始写代码了:
# -->>>托马<<<---
from PIL import Image
import pytesseract
# 打开图片
image = Image.open(r'PIC/3.jpg')
# 灰度处理
image1 = image.convert('L')
# 识别图片,lang是对应的字体
text = pytesseract.image_to_string(image,lang='eng')
# 打印识别内容
print(text)
好了,这里是个简单的例子。验证码可以自己百度上找。打开图片这里的路径根据自己的实际情况更改。lang='eng'这里,也可以不要,这里的意思就是识别中文还是英文,如果是中文那么需要另外下来语言包。默认英文。
这里,有很多朋友跑起来之后会报错,提示你什么什么path没有发现或者不对的。改一下配置就好。上述代码中按住ctrl鼠标点击image_to_string方法,会进入到pytesseract.py文件,一直上滑或者CTRL+F搜索关键字。
将此处注释的改成你的Tesseract-OCR文件内的tesseract.exe路径即可,然后重启电脑。
注意:这样的方法可以识别验证码码,但是准确率太低了,甚至有很多不能识别。所以介绍到此结束。
ddddocr
这个包就比上一个方法强很多了。识别率也是比较不错的。但是呢,作者比较的流氓。大佬很强但是也很流氓。至于为什么这么说,各位去试试就知道了。
pip install ddddocr
好了玩笑到这里。大家不喜欢作者的库每次打开后都有一些介绍信息的可以去源代码删了,下面会介绍。
from ddddocr import DdddOcr
# 实例化方法
ocr = DdddOcr()
# 打开图片
file = open(r'./PIC/7.png','rb')
# 读取图片
img = file.read()
# 识别图片
result = ocr.classification(img)
# 打印内容
print(result)
上述例子,验证码自己备好哦。上述简单的例子就能完成验证码图片识别了。可以自己去试试。
DdddOcr是里面的一个类方法。里面还有一些其他的功能各位大佬自己去试试吧。本文只介绍图片识别哦。上面比较的好理解吧。那么我们进入实战。
"""
体验管理员: admin
密码: shopxo
https://d2.shopxo.vip/admin.php?s=admin/logininfo.html
"""
是一个后台管理的地址,请不要乱删改里面的内容,作者开源不易。
我们先用最简单的脚本来写一下:
# -->>>托马<<<---
from PIL import Image
from ddddocr import DdddOcr
from selenium import webdriver
from time import sleep
"""
体验管理员: admin
密码: shopxo
https://d2.shopxo.vip/admin.php?s=admin/logininfo.html
"""
fox = webdriver.Firefox()
fox.get('https://d2.shopxo.vip/admin.php?s=admin/logininfo.html')
fox.find_element_by_xpath("//input[@name='accounts']").send_keys('admin')
fox.find_element_by_xpath("//input[@name='pwd']").send_keys('shopxo')
pic = fox.find_elements_by_xpath("//span[@class='am-input-group-btn']")[1]
sleep(2)
# 保存截图
fox.save_screenshot('./PIC/6.png')
# 获取位置
location = pic.location
print(location)
# 获取大小
pic_size = pic.size
print(pic_size)
# 确定所需要的图片大小
rangle = (int(location['x']-5), int(location['y']-5), int(location['x'] + pic_size['width']+11),
int(location['y'] + pic_size['height']+7))
# 打开之前截图图片
image = Image.open('./PIC/6.png')
# 开始裁剪
image1 = image.crop(rangle)
# 保存裁剪后的截图
image1.save('./PIC/7.png')
# 实例化类方法
ocr = DdddOcr()
# 打开图片,二进制形式
file = open(r'./PIC/7.png','rb')
# 读取图片
img = file.read()
# 识别图片验证码
result = ocr.classification(img)
print(result)
fox.find_element_by_xpath("//input[@name='verify']").send_keys(result)
fox.find_element_by_xpath("//*[text()='登录']").click()
很多人看了这里是不是麻了,哈哈哈,我自己写的也看麻了。后续会优化在框架中体现。亦或者出一篇优化的文。
基础脚本麻,我们简单说说其中重要的,selenium基础就不用多说了。最主要的是截图验证码那部分,也就是代码中的rangle变量。这里需要根据实际情况进行调整,把整个验证码框截取下来,也就是在原来的坐标上,进行加减乘除。
代码中有x+y的一部分代码,这里是为什么呢,是我们获取到的一个验证码是根据坐标轴来的,也就是说,这里的x+y实则取得是长宽的一个范围。我想截取一个长方形,我需要知道长跟宽吧。那么如何知道了,那就是此处的取值了。就好歹我从左下角开始取值,我想得到一个验证码这样长方形的图,那么终点只能是右上角。
注意:这里验证码识别只是举例了,实际情况还是需要根据项目来才行, 毕竟这个库识别率虽然OK,但是难免也会有出错的时候。所以,在用技术自动登录的过程中,还需要做很多的判断来避免错误让它自己登录自己判断的更流畅。