一.問題背景
自動化測試時,注冊頁面需要輸入驗證碼,為此需要截取下驗證碼圖檔,然後調用識别出其中文字資訊,以模拟輸入
阿裡雲驗證碼識别api連結
通過此連結可以檢視此api調用資訊:

如下是api調試結果:
APPcode擷取方式
二.python代碼實作圖檔base64編碼生成及阿裡雲驗證碼識别
前者是getBase64Code函數,後者是getTextFromCode函數
#coding=utf-8
from selenium import webdriver
from PIL import Image
from ShowapiRequest import ShowapiRequest
import time
import os
import random
import base64
import urllib, urllib.request, sys,urllib.parse
import ssl
import json
#urllib2子產品直接導入就可以用,在python3中urllib2被改為urllib.request
'''全局變量driver'''
option = webdriver.ChromeOptions()
option.add_experimental_option("excludeSwitches", ['enable-automation', 'enable-logging'])
driver = webdriver.Chrome(options=option)
# driver = webdriver.Chrome()
def initDriver():
'''初始化driver'''
driver.get("你的測試網址")
#等待頁面加載完畢
time.sleep(5)
def findElement(key):
'''根據id定位擷取元素'''
element = driver.find_element_by_id(key)
return element
def getRandomValue():
'''擷取随機輸入值'''
randomVal = "".join(random.sample("1234567abcdefg",6))
return randomVal
def saveScreenshot(shotPath):
'''儲存注冊頁面截圖"D:\D1\code\AutoTest\python_ui_autotest\SeleniumPython\chapter2\image\shot1.png"'''
driver.save_screenshot(shotPath)
def saveCode(shotPath,codePath):
'''儲存驗證碼圖檔'''
'''2.定位到矩形區域'''
verifyCodeEle = driver.find_element_by_id("getcode_num")
loc = verifyCodeEle.location #<class 'dict'> || {'x': 552, 'y': 527}
left = loc.get("x")
top = loc.get("y")
#注意verifyCodeEle.size是dict,需要通過get方法
right = verifyCodeEle.size.get("width") + left
height = verifyCodeEle.size.get("height") + top
print(left,top,right,height)
'''3.裁剪儲存,使用Pillow對圖檔進行裁剪'''
#擷取視窗可視範圍的width和height
html = driver.find_element_by_tag_name("html")
#設定圖檔重新打開的width和height
resize_width = html.size['width']
resize_height = html.size['height']
#resize圖檔,調整分辨率
img = Image.open(shotPath)
resize_img = img.resize((resize_width, resize_height), Image.BILINEAR)
cropped = resize_img.crop((left, top, right, height)) #左,上,右,下
cropped.save(codePath)
'''*****************************************************************************'''
def getBase64Code(codePath):
'''python生成圖檔的base64編碼'''
with open (codePath,'rb') as f:
base64_data=base64.b64encode(f.read())
s=base64_data.decode()
data='data:image/jpeg;base64,%s'%s
return data
def getTextFromCode(codePath):
'''阿裡雲解析驗證碼圖檔,傳回驗證碼中文字資訊'''
base64Code = getBase64Code(codePath)
host = 'https://302307.market.alicloudapi.com'
path = '/ocr/captcha'
method = 'POST'
appcode = 'd23f3e0a2af44de7a95503d8355134d0'
querys = ''
bodys = {}
url = host + path
bodys['image'] = base64Code
bodys['maxlength'] = "5"
bodys['minlength'] = "5"
bodys['type'] = "1001"
##将自定義data轉換成标準格式,其中,
#urlencode函數作用是将字元串進行url編碼
#.encode函數:送出類型不能為str,需要為byte類型
post_data = urllib.parse.urlencode(bodys).encode('utf-8')
request = urllib.request.Request(url, post_data)
request.add_header('Authorization', 'APPCODE ' + appcode)
#根據API的要求,定義相對應的Content-Type
request.add_header('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8')
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
#發送請求,傳回響應
response = urllib.request.urlopen(request, context=ctx)
#read()讀取内容,需要decode()解碼,轉換成str類型
content = response.read().decode('utf-8')
if (content):
print("content is------>",content)
res = json.loads(content)["data"]["captcha"]
print("res is------>",res)
return res
'''*****************************************************************************'''
def main():
try:
initDriver()
shotPath = "D:\D1\code\AutoTest\python_ui_autotest\SeleniumPython\chapter2\image\shot.png"
codePath = "D:\D1\code\AutoTest\python_ui_autotest\SeleniumPython\chapter2\image\code.png"
randomEmail = getRandomValue() + "@163.com"
randomUserName = getRandomValue()
randomPass = getRandomValue()
findElement("register_email").send_keys(randomEmail)
findElement("register_nickname").send_keys(randomUserName)
findElement("register_password").send_keys(randomPass)
saveScreenshot(shotPath)
saveCode(shotPath,codePath)
verifyCode = getTextFromCode(codePath)
findElement("captcha_code").send_keys(verifyCode)
time.sleep(5)
findElement("register-btn").click() #點選注冊按鈕
finally:#無論是否發生異常都會執行
try:
os.system('taskkill /im chromedriver.exe /F')
except:
print("chrome driver程序不存在")
main()
運作結果如下:
按照預期結果能注冊成功
參考文章:
https://www.jb51.net/article/168172.htm
https://blog.csdn.net/u010899985/article/details/79595187
https://www.imooc.com/article/49788