Web自動化—解決登錄頁面隨機驗證碼問題

一、拋出問題

在日常的測試工作中,遇到了這樣一個登錄頁面,如下圖:

 

像我們之前做過UI自動化的同學就知道,自動輸入帳號和密碼,這個簡單,但是怎麼樣來識別驗證碼呢?驗證碼的形式有多種,有純數字的,純字母的,有字母和數字的,有計算的等等;而且每次都是隨機出現的,這種情況我們怎麼來識別呢?如何解決這個難題?

二、分析問題

在測試環境中,遇到這種情況,分析了一下,大概有以下幾種思路:

1、  讓開發在測試環境中,去掉驗證碼;

2、  測試環境中,設置一個萬能的驗證碼;

3、  通過cookie繞過登錄;

4、  通過自動識別技術,來識別驗證碼;

對於以上方法,前三種都不太好方便,需要依賴上游,所以,我們儘可能的自己單槍匹馬去解決。現在主要來講第4種方法。

自動識別技術,其實就是通過第三方網站的力量來實現快速識別,花1塊錢,就能用500次,有現成的東西,直接藉助打碼平台的自動識別技術使用就行,少喝一瓶礦泉水的錢,就能幫我們解決大問題。我們這裡以某一個打碼平台為示例來講解:

百度搜索:圖鑑打碼平台,找到結果,並點擊進入。

點擊開發文檔,可以看到導航條可以用多種程式語言將其寫好了,這些都是可以直接拿來使用的;我們這裡以python語言為例,藉助使用一下。但是,需要花錢,也就充值1塊錢,就可以用500次。為了,第一步就是要在這個打碼平台上進行註冊,登錄,再充值1元即可。有以下重要資訊需要用到:你的帳號和密碼。

 

接下來,我們對這段python程式碼來簡單分析一下:

 

比如,你的驗證碼是純數字,你就傳1;你的驗證碼是純英文,你就傳2;如果你的驗證碼是數字字母混合的,那就傳3;像我遇到的,是計算題驗證碼,我就傳了11。

=================================================================

那麼,我們先來寫一下思路:

# 第一步:打開瀏覽器,訪問登錄頁面

    # 1.1啟動瀏覽器

    # 1.2 打開後台監控平台的登錄頁面

# 第二步:輸入帳號、密碼

    # 輸入帳號

    # 輸入密碼

# 第三步:識別驗證碼圖片中的內容

    # 3.1截取網站中的驗證碼圖片

            # 3.1.1、對當前網頁進行截圖,並保存為圖片

            # 3.1.2  定位頁面的圖片元素,

            # 3.1.3 獲取圖片在頁面中的坐標位置(此處計數位置要考慮螢幕的縮放比例)

            # 驗證碼左邊界位置

            # 驗證碼上邊界位置

            # 驗證碼右邊界位置

            # 驗證碼下邊界位置

            # 3.1.4 通過驗證碼的位置進行截圖

            # 3.1.5 保存截取下來的驗證碼為code.png的圖片

    # 3.2 調用驗證碼識別的方法去識別

# 第四步:輸入識別之後的結果,點擊登錄

    # 4.1 輸入計算結果之後的驗證碼

    # 4.2點擊登錄按鈕

# 第五步:關閉瀏覽器

======================================================================

所以,重點就在第三步,尤其要注意一個細節,就是螢幕縮放比。

 

如果你忘記這裡,有可能對驗證碼截圖截不到。

接下來上程式碼

from selenium import webdriver
import base64
import json
import requests
from PIL import Image


# 64位編碼流
def base64_api(uname, pwd, img, typeid):
    with open(img, 'rb') as f:
        base64_data = base64.b64encode(f.read())
        b64 = base64_data.decode()
    data = {"username": uname, "password": pwd, "typeid": typeid, "image": b64}
    result = json.loads(requests.post("//api.ttshitu.com/predict", json=data).text)
    if result['success']:
        return result["data"]["result"]
    else:
        return result["message"]


# 第一步:打開瀏覽器,訪問登錄頁面
# 1.1啟動瀏覽器
driver = webdriver.Chrome()
# 1.2 打開後台監控平台的登錄頁面
driver.get('')

# 第二步:輸入帳號、密碼
# 輸入帳號
driver.find_element_by_xpath('//input[@placeholder="帳號"]').send_keys('')
# 輸入密碼
driver.find_element_by_xpath('//input[@placeholder="密碼"]').send_keys('')

# 第三步:識別驗證碼圖片中的內容
# 3.1截取網站中的驗證碼圖片
# 3.1.1、對當前網頁進行截圖,並保存為page.png的圖片
driver.save_screenshot('page.png')
# 3.1.2  定位頁面的圖片元素,
pic_ele = driver.find_element_by_xpath('//div//img')
# 3.1.3 獲取圖片在頁面中的坐標位置(此處計數位置要考慮螢幕的縮放比例)
rec = pic_ele.rect
# 驗證碼左邊界位置
left = rec['x'] * 1.50
# 驗證碼上邊界位置
top = rec['y'] * 1.50
# 驗證碼右邊界位置
right = (rec['x'] + rec['width']) * 1.50
# 驗證碼下邊界位置
button = (rec['y'] + rec['height']) * 1.50
location = (left, top, right, button)

# 3.1.4通過驗證碼的位置進行截圖
page = Image.open('page.png')
code_pic = page.crop(location)
# 3.1.5 保存截取下來的驗證碼為code.png的圖片
code_pic.save('code.png')

# 3.2 調用驗證碼識別的方法去識別
result = base64_api(uname='', pwd='', img='code.png', typeid=11)
print("識別的結果是:", result)

# 第四步:輸入識別之後的結果,點擊登錄
# 4.1 輸入計算結果之後的驗證碼
driver.find_element_by_xpath('//input[@placeholder="驗證碼"]').send_keys(result)

# 4.2點擊登錄按鈕
driver.find_element_by_xpath('//button[@type="button"]').click()

對程式碼進行講解和注意的細節。這個腳本是可以直接複製粘貼拿過去用的

三、總結思路

結尾要簡單聊兩句:首先,這個打碼平台不止一個,還有其他的打碼平台的也可以藉助使用,也會有類似的開發文檔程式碼,他山之石,可以攻玉,只需花1塊錢就可以,任何一個打碼平台都行。至於開發文檔的語言,也是可以任選的,有的web自動化是python寫的,有的是java寫的,甚至有的是javascript寫的,都行,自由選擇即可。

因為,我們基本可以總結出如下思路:

1、  任選一個打碼平台,註冊登錄並充值1元

2、  進入該平台的開發文檔,選擇你所用到的程式語言一類,複製粘貼程式碼

3、  把你剛才所充值的平台的帳號、密碼;傳參傳進去,對應的typeid也改一下

4、  檢查你的電腦螢幕縮放比例,在所對應的坐標位置程式碼塊中乘以比例

最後,在pycharm,run一下,會給你期望的驚喜那般,哇塞,賊6

好了,以上就是很簡單很實用並且性價比極高的解決方法,不需要跟開發吵架,讓他特意為了方便你測試,故意改程式碼塊;也不需要跟著學習其他深度的OCR識別技術,太耗時了,還不一定學的會;我們就選擇這種單槍匹馬的思路,干就完事了。

親自有效,有任何問題,可留言,筆者可通過向日葵遠程連接你電腦,幫你操作好。