初稿代码,可以忽略不计(自己留着看)

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2020/01/15 13:27
# @Author : zc
# @File : 115test.py
from selenium import webdriver
from selenium.webdriver.common.by import By
from time import sleep
from PIL import Image,ImageEnhance
import pytesseract
imgPath1 = "/Users/zhangc/zhangchang/111/test/img/识别失败图片.png"
imgPath = "/Users/zhangc/zhangchang/111/test/img/img.png"
driver = webdriver.Chrome("/Users/zhangc/zhangchang/111/test/chromedriver")
def remove(string):
return string.replace(" ","")
def open(code):
url = 'http://192.168.2.213:9100'
driver.get(url)
driver.maximize_window()
login(code)
def login(code):
if (code == "") | (len(remove(code)) != 4):
getCodeImg()
else:
# 输入用户名
telephone = driver.find_element(By.NAME,"telephone")
telephone.clear()
telephone.send_keys("13642040631")
# 输入密码
password = driver.find_element(By.NAME,"password")
password.clear()
password.send_keys("123456")
# 输入验证码
code_loc = driver.find_element(By.NAME,"code")
code_loc.clear()
code_loc.send_keys(code)
# 点击登录按钮
button = driver.find_element(By.XPATH,"//button[@type='button']")
button.click()
try:
# 后台获取验证码校验内容
text1 = driver.find_element(By.CSS_SELECTOR, ".el-message__content").text
print(text1)
while text1 == "":
button.click()
text1
# 前台获取验证码校验内容
text2 = driver.find_element(By.CSS_SELECTOR, ".el-el-form-item__error").text
print(text2)
if text1 == "验证码不正确":
print("验证码不正确")
driver.find_element(By.XPATH, "//div[@class='divIdentifyingCode']/img").click()
getCodeImg()
code2 = test()
login(code2)
elif text2 == "请输入正确的验证码":
print("请输入正确的验证码")
driver.find_element(By.XPATH, "//div[@class='divIdentifyingCode']/img").click()
getCodeImg()
code2 = test()
login(code2)
else:
print("登陆成功!")
except:
print("进入首页!!!!")
pass
def getCodeImg():
'''获取code图片'''
size2 = driver.get_window_size()
print("页面的总size:"+str(size2))
img_el = driver.find_element(By.XPATH,"//div[@class='divIdentifyingCode']/img")
# 获取图片的坐标
location = img_el.location
print("页面坐标点的size:"+str(location))
# 获取图片的大小
size = img_el.size
print("验证码的size:"+str(size))
left = location['x']/size2['width']
top = location['y']/size2['height']
right = (location['x'] + size['width'])/size2['width']
bottom = (location['y'] + size['height'])/size2['height']
print(left,top,right,bottom)
# 截图操作
driver.get_screenshot_as_file(imgPath)
imgSize = Image.open(imgPath).size
print("截图的size:"+str(imgSize))
sleep(2)
img = Image.open(imgPath).crop((left*imgSize[0],
top*imgSize[1]+100,
right*imgSize[0]+20,
bottom*imgSize[1]+150))
img = img.convert('L') #转换模式:L | RGB
img = ImageEnhance.Contrast(img)#增强对比度
img = img.enhance(2.0) #增加饱和度
img.save(imgPath)
def test():
img2 = Image.open(imgPath)
code = pytesseract.image_to_string(img2).strip()
print("=============输出的验证码为:"+remove(code))
while (code == "") | (len(remove(code)) != 4):
# 重新获取验证码
driver.find_element(By.XPATH, "//div[@class='divIdentifyingCode']/img").click()
getCodeImg()
img2 = Image.open(imgPath)
code = pytesseract.image_to_string(img2).strip()
if code == "":
print("code获取为空值=================")
continue
elif len(remove(code)) != 4:
print("code获取不是4位数字=============")
continue
else:
print("识别成功!")
# break
break
print("=============输出的验证码为:" + remove(code))
return remove(code)
if __name__ == '__main__':
code = ""
open(code)
code1 = test()
login(code1)
# 页面的总size:{'width': 1206, 'height': 1129}
# 页面坐标点的size:{'x': 961, 'y': 518}
# 验证码的size:{'height': 28, 'width': 70}
# 0.796849087893864 0.4588131089459699 0.8548922056384743 0.48361381753764393
# 截图的size:(2412, 1950)
View Code
====================下面看正文=========================
之前有个问题一直在困扰着我,如何获取验证码的值

后来查询大神们的文章得知:
用pytesseract库来读取图片的文字。
先安装两个库:
# python有着更加优雅的方式调用系统的tesseract工具,首先安装pytesseract模块;pytesseract是对tesseract的封装,要和PIL联合使用 # 安装pytesseract sudo pip install pytesseract # 安装图片处理器PIL pip install pillow
好了接下来看看我是怎么一步一步实现的吧
第一步、保存验证码图片
import pytesseract
from selenium import webdriver
from selenium.webdriver.common.by import By
from time import sleep
from PIL import Image,ImageEnhance
class LoginCode(object):
# 用户名框元素
telephone_loc = (By.NAME,"telephone")
# 密码框元素
password_loc = (By.NAME,"password")
# 验证码框元素
code_loc = (By.NAME,"code")
# 登录按钮元素
button_loc = (By.XPATH,"//button[@type='button']")
# 验证码图片元素
img_el_loc = (By.XPATH, "//div[@class='divIdentifyingCode']/img")
# 验证码错误提示元素
codeErrMsg_loc = (By.CSS_SELECTOR, ".el-message__content")
imgPath = "/Users/zhangc/zhangchang/111/test/img/img.png"
driver = webdriver.Chrome("/Users/zhangc/zhangchang/111/test/chromedriver")
def find_element(self,*loc):
# 实验得知方法中的参数loc↑加上*,定位会更稳定
'''定位单个元素'''
return self.driver.find_element(*loc)
def getCodeImg(self):
'''获取验证码图片'''
# 验证码图片的元素定位
img_el = self.find_element(*self.img_el_loc)
# 获取整个浏览器的size
chromeSize = self.driver.get_window_size()
print("页面的总size:"+str(chromeSize)) # 页面的总size:{'width': 1202, 'height': 1129}
# 获取图片的坐标
self.location = img_el.location
print("页面坐标点的size:"+str(self.location)) # 页面坐标点的size:{'x': 959, 'y': 518} x:指的图片左边距;y:指的图片上边距
# 获取图片的大小
imgSize = img_el.size
print("验证码的size:"+str(imgSize)) # 验证码的size:{'height': 28, 'width': 70}
left = self.location['x']/chromeSize['width'] # 左边距占整个浏览器的百分比
top = self.location['y']/chromeSize['height'] # 上边距占整个浏览器的百分比
right = (self.location['x'] + imgSize['width'])/chromeSize['width'] # 右边距占整个浏览器的百分比
bottom = (self.location['y'] + imgSize['height'])/chromeSize['height'] # 下边距占整个浏览器的百分比
print(left,top,right,bottom) # 0.7978369384359401 0.4588131089459699 0.8560732113144759 0.48361381753764393
# 浏览器截屏操作
self.driver.get_screenshot_as_file(self.imgPath)
screenshotImgSize = Image.open(self.imgPath).size
print("截图的size:"+str(screenshotImgSize)) # 截图的size:(2404, 1950) 宽:2404,高:1950
sleep(2)
# 从文件读取截图,截取验证码位置再次保存
img = Image.open(self.imgPath).crop((
# left*screenshotImgSize[0],
# top*screenshotImgSize[1]+100,
# right*screenshotImgSize[0]+20,
# bottom*screenshotImgSize[1]+150
left * screenshotImgSize[1]+350, # 左边距百分比*截图的高≈截图左边距,再加上微调的距离+350
top * screenshotImgSize[0]-100, # 上边距百分比*截图的宽≈截图上边距,再加上微调的距离-100
right * screenshotImgSize[1]+400, # 右边距百分比*截图的高≈截图右边距,再加上微调的距离+400
bottom * screenshotImgSize[0]-50 # 上边距百分比*截图的宽≈截图下边距,再加上微调的距离-50
))
img = img.convert('L') # 转换模式:L | RGB
img = ImageEnhance.Contrast(img) # 增强对比度
img = img.enhance(2.0) # 增加饱和度
img.save(self.imgPath) # 再次保存图片
getCodeImg(self)方法,获取页面中验证码图片的截图:

第二步、循环获取验证码截图的code
为什么要循环获取呢,一次获取不就可以了吗,原因是图片识别文字不准确,经常会识别为空或者不是4位数的值。
所以要循环做判断,下面上代码:
import pytesseract
from selenium import webdriver
from selenium.webdriver.common.by import By
from time import sleep
from PIL import Image,ImageEnhance
class LoginCode(object):
# 用户名框元素
telephone_loc = (By.NAME,"telephone")
# 密码框元素
password_loc = (By.NAME,"password")
# 验证码框元素
code_loc = (By.NAME,"code")
# 登录按钮元素
button_loc = (By.XPATH,"//button[@type='button']")
# 验证码图片元素
img_el_loc = (By.XPATH, "//div[@class='divIdentifyingCode']/img")
# 验证码错误提示元素
codeErrMsg_loc = (By.CSS_SELECTOR, ".el-message__content")
imgPath = "/Users/zhangc/zhangchang/111/test/img/img.png"
driver = webdriver.Chrome("/Users/zhangc/zhangchang/111/test/chromedriver")
def remove(self,string):
'''字符串去除空格'''
return string.replace(" ","")
def find_element(self,*loc):
# 实验得知方法中的参数loc↑加上*,定位会更稳定
'''定位单个元素'''
return self.driver.find_element(*loc)
def getCode(self):
'''获取图片的code'''
# 再次读取识别验证码
img = Image.open(self.imgPath)
code = pytesseract.image_to_string(img).strip()
print("=============输出的验证码为:" + self.remove(code))
return code
def loopGetCode(self):
'''循环判断获取正确的图片code'''
code = self.remove(self.getCode())
# 循环前获取code字数
codeNumBf = len(code)
# 如果获取图片的code值为空或者不满足4位数进行循环
while (code == "") | (codeNumBf != 4):
# 重新获取验证码
self.find_element(*self.img_el_loc).click()
self.getCodeImg() # 获取验证码图片
code = self.remove(self.getCode())
# 循环后获取code字数
codeNumAf = len(code)
if code == "":
print("code获取为空值=================")
continue
elif codeNumAf != 4:
print("code获取不是4位数字=============")
continue
else:
print("识别成功!")
# 识别成功退出循环
break
print("=============输出的验证码为:" + code)
# 输出满足条件的code
return code
核心方法是:
①getCode():先获取图片code值
②loopGetCode():如果获取的code值不符合条件,循环判断获取正确的图片code值
三、进行登录操作并判断验证码正确性
为什么登陆操作时还要判断验证码正确性呢,因为还是图片识别文字不准确,虽然识别出4位数但是并不是验证码图片中的值,所以需要再次判断,如果验证码错误就重新获取验证码的值。
import pytesseract
from selenium import webdriver
from selenium.webdriver.common.by import By
from time import sleep
from PIL import Image,ImageEnhance
class LoginCode(object):
# 用户名框元素
telephone_loc = (By.NAME,"telephone")
# 密码框元素
password_loc = (By.NAME,"password")
# 验证码框元素
code_loc = (By.NAME,"code")
# 登录按钮元素
button_loc = (By.XPATH,"//button[@type='button']")
# 验证码图片元素
img_el_loc = (By.XPATH, "//div[@class='divIdentifyingCode']/img")
# 验证码错误提示元素
codeErrMsg_loc = (By.CSS_SELECTOR, ".el-message__content")
imgPath = "/Users/zhangc/zhangchang/111/test/img/img.png"
driver = webdriver.Chrome("/Users/zhangc/zhangchang/111/test/chromedriver")
def open(self):
'''打开浏览器'''
url = 'http://192.168.2.213:9100'
self.driver.get(url)
self.driver.maximize_window()
self.driver.implicitly_wait(10)
# 获取验证码图片
self.getCodeImg()
def login(self,code):
'''进行登录操作'''
# 输入用户名
telephone = self.find_element(*self.telephone_loc)
telephone.clear()
telephone.send_keys("13642040631")
# 输入密码
password = self.find_element(*self.password_loc)
password.clear()
password.send_keys("123456")
# 输入验证码
code_loc = self.find_element(*self.code_loc)
code_loc.clear()
code_loc.send_keys(code)
# 点击登录按钮
button = self.find_element(*self.button_loc)
button.click()
sleep(0.5)
try:
# 后台获取验证码校验内容
codeErrMsg = self.find_element(*self.codeErrMsg_loc).text
print("打印后台:"+codeErrMsg)
if codeErrMsg == "验证码不正确":
print("验证码不正确111")
self.find_element(*self.img_el_loc).click()
self.getCodeImg()
self.loopGetCode_action()
else:
print("登陆成功!")
except:
print("进入首页!!!!")
pass
def loopGetCode_action(self):
'''循环验证code的正确性'''
resultCode = self.loopGetCode()
self.login(resultCode)
def login_action(self):
'''执行验证码登录操作'''
# 打开浏览器并获取验证码图片
self.open()
self.loopGetCode_action()
以上三步就是完整获取图片文字的方法了,虽然有点多但是都是必不可少的步骤。
==========================================================
注:需要安装tesseract,不然会提示:
# CHANGE THIS IF TESSERACT IS NOT IN YOUR PATH, OR IS NAMED DIFFERENTLY<br />pytesseract.pytesseract.TesseractNotFoundError: tesseract is not installed or it's not in your path<br />
未找到tesseract的路径,需要进入pytesseract.py文件

# Mac安装tesseract brew install --with-training-tools tesseract # 查看版本 tesseract -v tesseract 4.0.0 leptonica-1.77.0 libgif 5.1.4 : libjpeg 9c : libpng 1.6.36 : libtiff 4.0.10 : zlib 1.2.11 : libwebp 1.0.2 : libopenjp2 2.3.0 Found AVX2 Found AVX Found SSE # 查看安装路径 which tesseract /usr/local/bin/tesseract
==========================================================
下面上完整代码:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2020/01/15 13:27
# @Author : zc
# @File : 115test.py
import pytesseract
from selenium import webdriver
from selenium.webdriver.common.by import By
from time import sleep
from PIL import Image,ImageEnhance
class LoginCode(object):
# 用户名框元素
telephone_loc = (By.NAME,"telephone")
# 密码框元素
password_loc = (By.NAME,"password")
# 验证码框元素
code_loc = (By.NAME,"code")
# 登录按钮元素
button_loc = (By.XPATH,"//button[@type='button']")
# 验证码图片元素
img_el_loc = (By.XPATH, "//div[@class='divIdentifyingCode']/img")
# 验证码错误提示元素
codeErrMsg_loc = (By.CSS_SELECTOR, ".el-message__content")
imgPath = "/Users/zhangc/zhangchang/111/test/img/img.png"
driver = webdriver.Chrome("/Users/zhangc/zhangchang/111/test/chromedriver")
def remove(self,string):
'''字符串去除空格'''
return string.replace(" ","")
def find_element(self,*loc):
# 实验得知方法中的参数loc↑加上*,定位会更稳定
'''定位单个元素'''
return self.driver.find_element(*loc)
def open(self):
'''打开浏览器'''
url = 'http://192.168.2.213:9100'
self.driver.get(url)
self.driver.maximize_window()
self.driver.implicitly_wait(10)
# 获取验证码图片
self.getCodeImg()
def getCodeImg(self):
'''获取验证码图片'''
# 验证码图片的元素定位
img_el = self.find_element(*self.img_el_loc)
# 获取整个浏览器的size
chromeSize = self.driver.get_window_size()
print("页面的总size:"+str(chromeSize)) # 页面的总size:{'width': 1202, 'height': 1129}
# 获取图片的坐标
self.location = img_el.location
print("页面坐标点的size:"+str(self.location)) # 页面坐标点的size:{'x': 959, 'y': 518} x:指的图片左边距;y:指的图片上边距
# 获取图片的大小
imgSize = img_el.size
print("验证码的size:"+str(imgSize)) # 验证码的size:{'height': 28, 'width': 70}
left = self.location['x']/chromeSize['width'] # 左边距占整个浏览器的百分比
top = self.location['y']/chromeSize['height'] # 上边距占整个浏览器的百分比
right = (self.location['x'] + imgSize['width'])/chromeSize['width'] # 右边距占整个浏览器的百分比
bottom = (self.location['y'] + imgSize['height'])/chromeSize['height'] # 下边距占整个浏览器的百分比
print(left,top,right,bottom) # 0.7978369384359401 0.4588131089459699 0.8560732113144759 0.48361381753764393
# 浏览器截屏操作
self.driver.get_screenshot_as_file(self.imgPath)
screenshotImgSize = Image.open(self.imgPath).size
print("截图的size:"+str(screenshotImgSize)) # 截图的size:(2404, 1950) 宽:2404,高:1950
sleep(2)
# 从文件读取截图,截取验证码位置再次保存
img = Image.open(self.imgPath).crop((
# left*screenshotImgSize[0],
# top*screenshotImgSize[1]+100,
# right*screenshotImgSize[0]+20,
# bottom*screenshotImgSize[1]+150
left * screenshotImgSize[1]+350, # 左边距百分比*截图的高≈截图左边距,再加上微调的距离+350
top * screenshotImgSize[0]-100, # 上边距百分比*截图的宽≈截图上边距,再加上微调的距离-100
right * screenshotImgSize[1]+400, # 右边距百分比*截图的高≈截图右边距,再加上微调的距离+400
bottom * screenshotImgSize[0]-50 # 上边距百分比*截图的宽≈截图下边距,再加上微调的距离-50
))
img = img.convert('L') # 转换模式:L | RGB
img = ImageEnhance.Contrast(img) # 增强对比度
img = img.enhance(2.0) # 增加饱和度
img.save(self.imgPath) # 再次保存图片
def getCode(self):
'''获取图片的code'''
# 再次读取识别验证码
img = Image.open(self.imgPath)
code = pytesseract.image_to_string(img).strip()
print("=============输出的验证码为:" + self.remove(code))
return code
def loopGetCode(self):
'''循环判断获取正确的图片code'''
code = self.remove(self.getCode())
# 循环前获取code字数
codeNumBf = len(code)
# 如果获取图片的code值为空或者不满足4位数进行循环
while (code == "") | (codeNumBf != 4):
# 重新获取验证码
self.find_element(*self.img_el_loc).click()
self.getCodeImg() # 获取验证码图片
code = self.remove(self.getCode())
# 循环后获取code字数
codeNumAf = len(code)
if code == "":
print("code获取为空值=================")
continue
elif codeNumAf != 4:
print("code获取不是4位数字=============")
continue
else:
print("识别成功!")
# 识别成功退出循环
break
print("=============输出的验证码为:" + code)
# 输出满足条件的code
return code
def login(self,code):
'''进行登录操作'''
# 输入用户名
telephone = self.find_element(*self.telephone_loc)
telephone.clear()
telephone.send_keys("13642040631")
# 输入密码
password = self.find_element(*self.password_loc)
password.clear()
password.send_keys("123456")
# 输入验证码
code_loc = self.find_element(*self.code_loc)
code_loc.clear()
code_loc.send_keys(code)
# 点击登录按钮
button = self.find_element(*self.button_loc)
button.click()
sleep(0.5)
try:
# 后台获取验证码校验内容
codeErrMsg = self.find_element(*self.codeErrMsg_loc).text
print("打印后台:"+codeErrMsg)
if codeErrMsg == "验证码不正确":
print("验证码不正确111")
self.find_element(*self.img_el_loc).click()
self.getCodeImg()
self.loopGetCode_action()
else:
print("登陆成功!")
except:
print("进入首页!!!!")
pass
def loopGetCode_action(self):
'''循环验证code的正确性'''
resultCode = self.loopGetCode()
self.login(resultCode)
def login_action(self):
'''执行验证码登录操作'''
# 打开浏览器并获取验证码图片
self.open()
self.loopGetCode_action()
if __name__ == '__main__':
LoginCode().login_action()
四、附录
感谢下面的参考文章:
①感谢作者:薛定谔的DBA的《Python selenium自动化识别验证码模拟登录操作(二)》
②感谢作者:大王大大王的《python -使用pytesseract识别验证码中遇到的问题》
③感谢作者:潇雨危栏的《Mac上tesseract-OCR的安装配置》
④感谢作者:anno_ym雨?的《【Python】关于键盘键入值、str的与或非问题?【报错:TypeError: unsupported operand type(s) for |: 'str' and 'str'】》
⑤感谢作者:github_39655029的《Python中的条件判断、循环以及循环的终止》
⑥感谢作者:青灯夜游的《Python如何删除字符串中所有空格》
⑦感谢作者:silencement的《python如何跳出while循环》
⑧感谢作者:d0main的《Python读取图片尺寸、图片格式》
⑨感谢作者:奔跑的豆子_的《Python-获取图片的大小》
【说明】:本文章由站长整理发布,文章内容不代表本站观点,如文中有侵权行为,请与本站客服联系(QQ:254677821)!