python之web自動化驗證碼識別解決方案
驗證碼識別解決方案
對於web應用程序來講,處於安全性考慮,在登錄的時候,都會設置驗證碼,驗證碼的類型種類繁多,有圖片中辨別數字字母的,有點擊圖片中指定的文字的,也有算術計算結果的,再復雜一點就是滑動驗證的。諸如此類的驗證碼,對我們的系統增加了安全性的保障,但是對於我們測試人員來講,在自動化測試的過程中,無疑是一個棘手的問題。
1、web自動化驗證碼解決方案
一般在我們測試過程中,登錄遇到上述的驗證碼的時候,有以下種解決方案:
-
第一種、讓開發去掉驗證碼
-
第二種、設置一個萬能的驗證碼
-
第三種、通過cookie繞過登錄
-
第四種、自動識別技術識別驗證碼
2、自動識別技術識別驗證碼
前三種解決方案,想必大家都比較了解,本文重點闡述第四種解決方案,也就是驗證碼的自動識別,關於驗證碼識別這一塊,可以通過兩個方案來解決,
-
第一種是:OCR自動識別技術,
-
第二種是:通過第三方打碼平台的接口來識別。
OCR識別技術
OCR中文名稱光學識別, tesseract是一個有名的開源OCR識別框架,它與Leptonica圖片處理庫結合,可以讀取各種格式的圖像並將它們轉化成超過60種語言的文本,可以不斷訓練自己的識別庫,使圖像轉換文本的能力不斷增強。如果團隊深度需要,還可以以它為模板,開發出符合自身需求的OCR引擎。那么接下來給大家介紹一下如何使用tessract來識別我們的驗證碼。
關於OCR自動識別這一塊,需要大家安裝Tesseract,並配置好環境,步驟如下
1)、安裝tesseract
適用於Tesseract 3.05-02和Tesseract 4.00-beta的
Windows安裝程序下載地址:https://github.com/UB-Mannheim/tesseract/wik。
2)、加入培訓數據
tesseract 默認只能識別英文,如果您想要識別其他語言,則需要下載相應的培訓數據
下載地址:https://github.com/tesseract-ocr/tesseract/wiki/Data-Files,
-
下圖為中文數據包
我們只做中文,暫時下載一個中文的文字訓練數據就可以 ,然后將.traineddata文件復制到安裝之后的'tessdata'目錄中。C:\OCR\Tesseract-OCR\tessdata
3)、配置環境變量
要從任何位置訪問tesseract-OCR,您可能必須將tesseract-OCR二進制文件所在的目錄添加到Path變量中C:\OCR\Tesseract-OCR
。
-
安裝后tesseract之后 ,並不能直接在python中使用,我們要想在python中使用,需要安裝pytesseract模塊我們可以通過 pip 安裝
pip install pytesseract
-
python中識別驗證碼圖片內容
安裝好后。找一張驗證碼圖片,如下圖(命名為test.jpg),放在當前python文件同級目錄下面,
使用 PIL中的Image中的open方法打開驗證碼圖片,調用pytesseract.image_to_string方法,可以識別圖片中的文字,並且轉換成字符串,如下面代碼所示。
import pytesseract
from PIL import Image
pic = Image.open('test.jpg')
# pic 為打開的圖片,lang指定識別轉換的語言庫
text = pytesseract.image_to_string(pic,lang='chi_sim')
print(text)
通過上述方法能識別簡單的驗證碼,但是存在一定的問題,識別的精度不高,對於一些復雜一點,有干擾線的驗證碼無法正確識別出結果。
接下來給大家介紹一下第二種識別的方案,第三方的打碼平台識別
-
打碼平台識別驗證碼
第三方的打碼平台相對於OCR來講,優勢在於識別的精准度高,網絡上的第三方打碼平台很多,百度隨便一搜就有幾十個,這個給大家列舉幾個,如下所示:
網絡上的第三方打碼平台眾多,這里小編選擇超級鷹這個第三方的平台來給大家做演示。
首先登錄我們需要注冊登錄超級鷹這個網站 www.chaojiying.com,進入之后我們找到python對應的開發文檔並下載,
-
下載開發文檔
-
下載之后解壓縮,得到如下文件
-
第三方打碼平台的接口分析
我們打開chaojiying.py這個文件后,會發現這個文件中給出了的接口非常簡單,如下所示
首先第一步創建一個用戶對象:三個參數(賬號,密碼,軟件ID),賬號密碼就是該網站的賬號密碼,那么軟件ID呢?軟件ID我們可以在用戶中心找到軟件ID,然后進去點擊生成一個軟件ID(如下圖),
第二行代碼就是打開一個要識別的驗證碼圖片,並讀取內容,
第三行,調用PostPic方法識別驗證碼,兩個參數(驗證碼圖片內容,驗證碼類型),關於驗證碼類型,請參考該網站的價格體系(如下圖),根據驗證碼類型選擇對應的數值傳入。
結果提取:
PostPic返回的是一個字典類型的數據,識別的驗證碼在該字典中的pic_str這個鍵中
res = cjy.PostPic(im, 1902) # 1902 驗證碼類型 官方網站>>價格體系 3.4+版 print 后要加()
data = res['pic_str']
print(data)第三方接口給大家介紹到這里,接下來我們實際應用到登錄中去。
提示:打碼平台一般都是收費的(差不多是一分錢,識別一次)
3、自動識別驗證碼登錄案例
-
登錄案例
接下來以超級鷹這個網站為列,使用web自動化測試框架selenium來實現驗證碼識別自動登錄,
-
需要用到的庫有selenium、pillow、time,和我們上面下載的超級鷹的接口文件
-
環境安裝
-
1、selenium安裝
pip install selenium
-
2、chromedriver 安裝
# 下載地址
http://chromedriver.storage.googleapis.com/index.html-
下載和自己chrome瀏覽器對應的chromedriver版本,
-
配置環境變量
-
-
3、pillow模塊安裝(處理圖像的庫)
pip install pillow
-
-
實現步驟分析
-
1、獲取賬號密碼輸入框:輸入賬號密碼
-
2、獲取驗證碼圖片
-
將當前頁面截圖
-
選擇圖片元素,獲取上下左右位置
-
使用PIL模塊對頁面圖片進行再次截圖(獲取驗證碼圖片)
-
將驗證碼圖片保存
-
-
3、調用第三方接口識別驗證碼
-
-
5、點擊登錄
1
-
具體代碼實現
-
1、selenium打開登錄頁面
import time
from selenium import webdriver
from PIL import Image
from chaojiying import Chaojiying_Client
# 創建一個瀏覽器
browser = webdriver.Chrome()
# 訪問登錄頁面
url = 'http://www.chaojiying.com/user/mysoft/'
browser.get(url)
time.sleep(1) # 暫停一秒鍾 -
2、獲取賬號密碼輸入框:輸入賬號密碼
# 選擇賬號、密碼輸入欄,輸入對應的賬號密碼
input_user=browser.find_element_by_xpath('/html/body/div[3]/div/div[3]/div[1]/form/p[1]/input')
# 輸入賬號
input_user.send_keys('賬號')
input_pwd=browser.find_element_by_xpath('/html/body/div[3]/div/div[3]/div[1]/form/p[2]/input')
# 輸入密碼
input_pwd.send_keys('密碼') -
2、獲取驗證碼圖片
-
將當前頁面截圖
# 對當前頁面進行截圖
browser.save_screenshot('login.png') -
選擇圖片元素,獲取上下左右位置
-
# 選擇驗證碼圖片的元素
yzm_btn = browser.find_element_by_xpath('/html/body/div[3]/div/div[3]/div[1]/form/div/img')
# 獲取圖片元素的位置
loc = yzm_btn.location
# 獲取圖片的寬高
size = yzm_btn.size-
獲取驗證碼上下左右的位置,此處要注意查看電腦顯示的縮放比列(如下圖),根據比列乘以相應的系數,我這邊的顯示比列是125,那么對於的系數就是1.25(如果你的是150,那么就乘以1.5)
left = loc['x']*1.25 # 計算左邊界
top = loc['y']*1.25 # 計算上邊界
right = (loc['x'] + size['width'])*1.25 # 計算右邊界
botom = (loc['y'] + size['height'])*1.25 # 計算下邊界
# 將上下左右邊界值放到元祖中(注意順序:左 上 右 下)
local = (left, top, right, botom) -
-
使用PIL模塊對頁面圖片進行再次截圖(獲取驗證碼圖片),將驗證碼圖片保存
pic = PIL.Image.open('file')
pic.crop(local)
pic.sava('zym,png')
-
-
3、調用第三方接口識別驗證碼
# 識別驗證碼
cjy = Chaojiying_Client('賬號', '密碼', '軟件ID') # 用戶中心>>軟件ID 生成一個
im = open('yzm.png', 'rb').read() # 本地圖片文件路徑 來替換 a.jpg 有時WIN系統須要//
res = cjy.PostPic(im, 1902) # 1902 驗證碼類型
data = res['pic_str']
print(data) -
4、輸入驗證碼結果
# 在輸入框輸入驗證碼
yzm_input = browser.find_element_by_xpath('/html/body/div[3]/div/div[3]/div[1]/form/p[3]/input')
yzm_input.send_keys(data) -
5、點擊登錄
# 點擊登錄
submit = browser.find_element_by_xpath('/html/body/div[3]/div/div[3]/div[1]/form/p[4]/input')
submit.click()
-
import time
from selenium import webdriver
from PIL import Image
from chaojiying import Chaojiying_Client
# 創建一個瀏覽器
browser = webdriver.Chrome()
# 訪問登錄頁面
url = 'http://www.chaojiying.com/user/mysoft/'
browser.get(url)
time.sleep(1) # 暫停一秒鍾
# 選擇賬號、密碼輸入欄,輸入對應的賬號密碼
input_user = browser.find_element_by_xpath('/html/body/div[3]/div/div[3]/div[1]/form/p[1]/input')
input_user.send_keys('qq121292679')
input_pwd = browser.find_element_by_xpath('/html/body/div[3]/div/div[3]/div[1]/form/p[2]/input')
input_pwd.send_keys('546245426')
# 獲取驗證碼的圖片,並進行識別,將識別的結果,輸入到驗證碼輸入框中
# 對當前頁面進行截圖
browser.save_screenshot('login.png')
# 選擇驗證碼圖片的元素
yzm_btn = browser.find_element_by_xpath('/html/body/div[3]/div/div[3]/div[1]/form/div/img')
# 獲取圖片元素的位置
loc = yzm_btn.location
# 獲取圖片的寬高
size = yzm_btn.size
# 獲取驗證碼上下左右的位置
left = loc['x']*1.25
top = loc['y']*1.25
right = (loc['x'] + size['width'])*1.25
botom = (loc['y'] + size['height'])*1.25
val = (left, top, right, botom)
# 打開網頁截圖
login_pic = Image.open('login.png')
# 通過上下左右的值,去截取驗證碼
yzm_pic = login_pic.crop(val)
yzm_pic.save('yzm.png')
# 識別驗證碼
cjy = Chaojiying_Client('qq121292679', '546245426', '96001') # 用戶中心>>軟件ID 生成一個替換 96001
im = open('yzm.png', 'rb').read() # 本地圖片文件路徑 來替換 a.jpg 有時WIN系統須要//
res = cjy.PostPic(im, 1902) # 1902 驗證碼類型 官方網站>>價格體系 3.4+版 print 后要加()
data = res['pic_str']
print(data)
# 在輸入框輸入驗證碼
yzm_input = browser.find_element_by_xpath('/html/body/div[3]/div/div[3]/div[1]/form/p[3]/input')
yzm_input.send_keys(data)
# 點擊登錄
submit = browser.find_element_by_xpath('/html/body/div[3]/div/div[3]/div[1]/form/p[4]/input')
submit.click()