简介: 验证码识别的测试,因故需做一个自动的多用户注册的脚本
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、总结:有较多的注释,记录了一些操作思路。学习了验证码的初级识别技术。