python验证码识别----总结笔记

一、环境准备:

任务 python验证码识别
语言 python 版本3.7
语言工具 pycharm 版本2018.2.2
工具 selenium 版本3.14
技术1 接口识别库 request
技术2 图片切割库 pillow

二、方法
1、万能能验证码—(缺点:不算模拟用户行为)
2、注释验证码相关的后台代码(缺点:繁琐,需要修改代码)
3、OCR技术(python库缺点,识别率低于20%)
4、保存服务端的cookie值(保留成功状态。缺点:并未做登录操作,跳过这个问题,而不是解决这个问题)
5、电脑使用内网ip地址,根据绑定的ip,不需要输入验证码
6、通过第三方工具,根据图片识别文字的工具。缺点:准确率低
7、通过第三方网站,易源网站,识别验证码。优点:准确率高,收费
8、输入验证码前,加入时间等待15秒。手动输入验证码。这个方式很笨

三、方法详解:万能验证码的设置:
1、如何查看系统是否存在万能验证码
(1)确认源代码位置
(2)了解MVC设计模式

1 2
model 模型层 数据库相关。新增用户信息时,通过user类创建一个user对象,就会向数据库保存用户信息。(user类里有和表对应的属性,user表存储用户信息)
view界面层 前端界面相关。用于收集和显示,用户的输入数据和服务器端的输出数据
control 控制层 处理业务逻辑 ,负责系统所有的业务逻辑处理

判断验证码是否登录成功,属于业务逻辑,代码在control层。找验证码代码,需要先找登录功能代码。分析登录页面网址

#登录页面地址
http://127.0.0.1/index.php?m=admin&c=public&a=login

#分析这三个参数
m=admin&c=public&a=login
m是模块,一个模块就是一个文件夹,一个文件夹对应某一个包名
c是controller,一个控制器,一般是一个类,也就是一个类文件
a是action,是一个行为动作,一个动作就是代码里的某个方法

根据这三个参数,找到对应的文件,在代码里找到验证码相关的代码
分析:假如代码中,含有:

#验证码不正确的时候,if条件的判断代码,代码里有
if((..........)!='1234')
	验证码不正确
#所以,万能验证码为1234

2、添加万能验证码

四、方法详解:第三方网站,识别验证码
1、要求:
UI自动化,需要测试时,尽量仿真的模拟用户行为
2、知识拓展:
易源网站(万维易源)封装了很多人工智能算法,登录网站搜索“验证码识别”,查询到相关接口。(收费)
网站:https://www.showapi.com/
3、使用此处的验证码接口需要什么东西?
(1)接口的使用环境,本质:调用了python的request库。所以使用时,需要request库。
如图,右侧【SDK下载】下载SDK是个压缩文件,解压后是一个py文件,放到工程目录下python验证码识别----总结笔记_第1张图片
(2)接口地址(识别英文_文件):http://route.showapi.com/184-4
接口收费,访问地址需要如下(购买后得到)
(a)App_ID:用户id、
(b)App_sceret:密码
(3)接口参数:
image:图片的地址
typeId:告诉接口,识别验证码的类型,(使用方法见网站内解释)
convert_to_jpg:不需要图片转换

3、解决方案:通过接口识别方法
优点:能识别具体内容,识别率为90%
缺点:只能是中文验证码和数字验证码、英文验证码(12306的无法识别)

四、实现
步骤:
(1)通过selenium启动浏览器,识别用户名和密码
(2)将浏览器中的登录信息进行截图,切割验证码(使用pillow库)
(3)针对浏览器中的验证码图片进行识别(易源网站的验证码识别接口)

五、原代码

#1.准备  使用Selenium启动浏览器识别用户名和密码
from PIL import Image
from selenium import webdriver
from ShowapiRequest import ShowapiRequest

jwdriver=webdriver.Chrome() #调用chrome浏览器
# 打开浏览器
jwdriver.get("http://127.0.0.1/iwebshop/index.php?controller=systemadmin")
#定位用户名输入框 并且输入内容
jwdriver.find_element_by_name("admin_name").send_keys("admin")
#定位密码输入框 并且输入内容
jwdriver.find_element_by_name("password").send_keys("123456")

#2.截图浏览器中的图片   进行切割(Pillow库)
# 从网页中提取出验证码图片
def  jietu():
    jwdriver.save_screenshot("C:/jw123all.png")
    # 使用坐标方式
    # 拿到验证码左上角坐标
    left_top=jwdriver.find_element_by_id("captchaImg").location
    print("左上角坐标",left_top)
    #左上角的x轴坐标
    #左上角的y轴坐标
    left=left_top['x']
    top= left_top['y']
# 取出右下角坐标
    # 获取图片的宽度+left x1 =====》  右坐标
    #获取图片的高度+top y1 =====》  下坐标
    #定位图片
    img=jwdriver.find_element_by_id("captchaImg")
    right=img.size['width']+left
    down=img.size['height']+top
    print("四个点的坐标",left,top,right,down)
    # 利用这四个坐标切割图片
    # 1.打开图片
    jw_img=Image.open("C:/jw123all.png")
    jw_img22=jw_img.crop((left,top,right,down))
    # 保存到硬盘上
    jw_img22.save("C:/jwyanzhengma.png")
#3.再针对验证码进行识别(易源的接口)
def   shibieyanzhengma():
    # 使用接口环境访问接口地址===>前提要注意联网
    jw1=ShowapiRequest("http://route.showapi.com/184-4","75989","10186a47079e4b8085ddb9bf168d3f70")
# 增加接口请求的参数
    jw1.addBodyPara("typeId","25")
    jw1.addBodyPara("convert_to_jpg","0")
    # 告诉接口识别的验证码图片文件
    jw1.addFilePara("image","c:/jwyanzhengma.png")
    #访问接口
    result=jw1.post().json()
    #从json提炼出有效的数据
    text=result['showapi_res_body']['Result']
    print("验证码是",text)
    return  text


if  __name__=="__main__":
    jietu()
    # 调用验证码函数获取结果
    yanzhengma=shibieyanzhengma()
    #将验证码放到网页上
    jwdriver.find_element_by_name("captcha").send_keys(yanzhengma)

六、我的练习代码

#导入webdriver类包
from PIL import Image
from selenium import webdriver
from ShowapiRequest import ShowapiRequest

#调用谷歌浏览器
webdriver = webdriver.Chrome()

#打开谷歌浏览器
webdriver.get('网址')
#定位元素,用户名,输入内容
webdriver.find_element_by_id('用户名的id').send_keys('user')
#定位元素,密码,输入内容
webdriver.find_element_by_id('密码的id').send_keys('111111')

#定义函数,截取验证码图片
def picture_screenshoot():
    #从网页中提取验证码图片
    webdriver.save_screenshot('D:\图片文件名.png')

    #获取验证码左上角坐标,格式:{'x':100,'y':200}
    left_top = webdriver.find_element_by_id('验证码的id').location
    print('左上角坐标',left_top)
    #X轴坐标
    x = left_top['x']
    #Y轴坐标
    y = left_top['y']

    #获取右下角的图标,先获取验证码的长和宽
    #宽度+x = x1
    ver_img = webdriver.find_element_by_id('验证码的id')
    x1 = ver_img.size['width']+x
    #高度+y = y1
    y1 = ver_img.size['hight']+y

    #使用四个坐标,切割验证码(使用pillow库),
    #需要安装pillow库,否则没有Imag对象

    #打开图片,在硬盘中的图片加载到内存中
    ver_img2 = Image.open('D:\图片文件名.png')
    #传入四个坐标值
    ver_img2.crop(x,y,x1,y1)
    #将截取的验证码保存到硬盘上
    ver_img2.save('D:\验证码图片名.png')

#定义函数,识别验证码
def verif_pic_identified():
    #使用接口环境,访问接口地址,必须联网访问
    req = ShowapiRequest('http://route.showapi.com/184-4')
    #增加接口请求参数
    req.addBodyPara('typeId','25')
    req.addBodyPara('convert_to_jpg', '0' )
    #告诉接口识别的验证码图片文件
    req.addFilePara('imag','D:\验证码图片名.png')
    #访问接口
    response = req.post().json()
    print(response)
    #从json中,提取有效验证码数据
    text = response['shouapi_res_body']['Result']
    print(text)
    return text


if __name__ == '__main__':
    picture_screenshoot()
    yanzhengma = verif_pic_identified()
    webdriver.find_element_by_id('验证码id').send_keys(yanzhengma)

七、无注释代码

from PIL import Image
from selenium import webdriver
from ShowapiRequest import ShowapiRequest

jwdriver=webdriver.Chrome() 
jwdriver.get("http://127.0.0.1/iwebshop/index.php?controller=systemadmin")
jwdriver.find_element_by_name("admin_name").send_keys("admin")
jwdriver.find_element_by_name("password").send_keys("123456")


def  jietu():
    jwdriver.save_screenshot("C:/jw123all.png")
    left_top=jwdriver.find_element_by_id("captchaImg").location
    print("左上角坐标",left_top)
    left=left_top['x']
    top= left_top['y']

    img=jwdriver.find_element_by_id("captchaImg")
    right=img.size['width']+left
    down=img.size['height']+top
    print("四个点的坐标",left,top,right,down)

    jw_img=Image.open("C:/jw123all.png")
    jw_img22=jw_img.crop((left,top,right,down))

    jw_img22.save("C:/jwyanzhengma.png")
    
#3.再针对验证码进行识别(易源的接口)
def   shibieyanzhengma():
    jw1=ShowapiRequest("http://route.showapi.com/184-4","75989","10186a47079e4b8085ddb9bf168d3f70")
    jw1.addBodyPara("typeId","25")
    jw1.addBodyPara("convert_to_jpg","0")
    jw1.addFilePara("image","c:/jwyanzhengma.png")
    result=jw1.post().json()
    text=result['showapi_res_body']['Result']
    print("验证码是",text)
    return  text

if  __name__=="__main__":
    jietu()
    yanzhengma=shibieyanzhengma()
    jwdriver.find_element_by_name("captcha").send_keys(yanzhengma)

你可能感兴趣的:(四,selenium)