验证码识别的测试【python】

简介: 验证码识别的测试,因故需做一个自动的多用户注册的脚本

1、查阅相关博客,建议使用的是Python+Selenium+PIL+Tesseract ,又有人推荐了Pytesser,不过这个Pytesser的安装还挺坑的。

2、开始参考的是:
http://www.th7.cn/Program/Python/201602/768304.shtml

以及这个

http://blog.csdn.net/lanfan_11/article/details/45558573

3、但测试了半天,无论我按照哪个方法,最终我都不能import pytesser , 一开始以为成功了,原来是我按照他的例子直接在pytesseract-v0.0.1的文件夹测试的脚本,那自然可以了。

4、毕竟第一次遇到需要这么折腾的第三方库,而且还是好几年前就停止更新了,干脆就直接把需要编写的py文件丢到这个pytesser文件夹来规避。

5、后来又发现有的博客推荐了pytesseract ,看名字应该是继承了pytesser,但是保持更新的,果然顺利安装,那么就是他了。那么更新下使用的工具组合为:Python+Selenium+PIL+pytesseract+Tesseract

6、剩下就是如何识别验证码的问题,由于测试的网站使用的.aspx的动态图,导致每次输入url得到不同的验证码。
所以一不做二不休,使用了截屏计算其验证码方位后单独识别的方案。(另外一个可操作方案是使用cookie)

过程:

# coding:utf-8
# python 3.5.2


from selenium.webdriver.support import ui as ui
from selenium.webdriver.common.keys import Keys #需要引入keys 包
from selenium.webdriver.common.action_chains import ActionChains
from selenium import webdriver
import pytesseract
import time
from PIL import Image,ImageEnhance

num = 400
# wait = ui.WebDriverWait(browser, 10)
# 已经人工测试了一个,所以从第二2个开始
for i in range(2, num+1):

    name_cn = 'aaa'        
    browser = webdriver.PhantomJS()
    browser.maximize_window()
    url = "http://www.wangzhi.com"
    browser.get(url)
    wait = ui.WebDriverWait(browser, 20)
    wait.until(lambda browser:browser.find_element_by_xpath("//*[@id=\"ussheng\"]"))
    shs1 = browser.find_element_by_xpath("//*[@id=\"ussheng\"]").send_keys("shengfen")
    shs2 = browser.find_element_by_xpath("//*[@id=\"uscity\"]").send_keys("xxshi")
    mhq = browser.find_element_by_xpath("//*[@id=\"usxian\"]").send_keys("yyqu")
    nling = browser.find_element_by_xpath("//*[@id=\"inscage\"]").send_keys("nianling")
    dwei = browser.find_element_by_xpath("//*[@id=\"worker\"]").send_keys("dizhi")
    name_input = browser.find_element_by_xpath("//*[@id=\"ustruename\"]").send_keys(name_cn + '%d'%i)

    # 选择性别,下拉框操作
    sex = browser.find_element_by_xpath("//*[@id=\"DropDownList1\"]")
    sex.find_element_by_xpath("//*[@id=\"DropDownList1\"]/option[2]").click()

    # 验证码识别,思路,右键保存验证码图片,识别数字或者字母。但是保存不能执行,失败
    ###############################################################################
    # # xpath: //*[@id="ValidImage"]
    # shi_bie_ma = browser.find_element_by_xpath("//*[@id=\"ValidImage\"]")
    # action = ActionChains(browser).move_to_element(shi_bie_ma)
    # action.context_click(shi_bie_ma)
    # action.send_keys(Keys.ARROW_DOWN)
    # action.send_keys('v')
    # action.perform()
    ###############################################################################



    # 通过下载图片后识别,发现是aspx 每次打开url都更新识别码,所以失败。看来只好一开始就截屏啦。

    # 截屏
    browser.get_screenshot_as_file('C:\\van\\image1.jpg')#比较好理解

    # 检测识别码坐标
    imgelement = browser.find_element_by_xpath('//*[@id="ValidImage"]') #定位验证码
    location = imgelement.location #获取验证码x,y轴坐标

    size=imgelement.size #获取验证码的长宽
    range=(int(location['x']),int(location['y']),int(location['x']+size['width']),int(location['y']+size['height'])) #写成我们需要截取的位置坐标

    im =Image.open('C:\\van\\image1.jpg')
    # 设置要裁剪的区域
    region = im.crop(range)     #此时,region是一个新的图像对象。
    #region.show()#显示的话就会被占用,所以要注释掉
    region.save("C:\\van\\image2.jpg")


     #--------------------图片增强+自动识别简单验证码-----------------------------
    #time.sleep(3)防止由于网速,可能图片还没保存好,就开始识别

    im=Image.open("C:\\van\\image2.jpg")
    imgry = im.convert('L')#图像加强,二值化
    sharpness =ImageEnhance.Contrast(imgry)#对比度增强
    sharp_img = sharpness.enhance(2.0)

    sharp_img.save("C:\\van\\image2.jpg")

    #http://www.cnblogs.com/txw1958/archive/2012/02/21/2361330.html

    #imgry.show()#这是分布测试时候用的,整个程序使用需要注释掉
    #imgry.save("E:\\image_code.jpg")
    im=Image.open("C:\\van\\image2.jpg")
    code = pytesseract.image_to_string(im)#code即为识别出的图片数字str类型
    print(code)
    #打印code观察是否识别正确

    #-------------------------------------------------------------------
    code_input = browser.find_element_by_xpath("//*[@id=\"txtCheckCode\"]").send_keys(code)
    # login
    browser.find_element_by_xpath("//*[@id=\"Button1\"]").click()
    print("fished,%d"%i)
    browser.quit()

7、程序分析:

  • 虽然使用的截屏然后识别验证码的方式,也许不是最优雅,不过可可以通过元素的imgelement.location 来获取验证码x,y轴坐标,从而可以得到精确的验证码截图区域,否则人工去调试也不是不行,但需要在画图板用鼠标尽可能准确的定位。
  • 增加了图片增加识别技术,加大了识别验证码的概率。
  • 这段代码的不足之处是没有检测验证码识别提交后,是否失败的判断,这主要是测试的网站标的,实在做的太烂了,点了二维码不会立刻提示错误与否,而是卡机。

8、总结:有较多的注释,记录了一些操作思路。学习了验证码的初级识别技术。