『心善淵』Selenium3.0基礎 — 21、Selenium實現繞過驗證碼進行登陸

1、驗證碼問題說明

對於Web應用來說,大部分的系統在用戶登錄時,都要求用戶輸入驗證碼。驗證碼的類型的很多,有字母數字的,有漢字的,甚至還要用戶輸入一條算術題的答案的。對於系統來說,使用驗證碼可以有效果的防止採用機器猜測方法對口令的刺探,在一定程度上增加了安全性。但對於測試人員來說,不管是進行性能測試,還是自動化測試都是一個棘手的問題。

2、處理驗證碼的方法

(1)去掉驗證碼

這是最簡單的方法,對於開發人員來說,只是把驗證碼的相關程式碼注釋掉即可,如果是在測試環境,這樣做可省去了測試人員不少麻煩,如果自動化腳本是要在正式環境跑,這樣就給系統帶來了一定的風險。(風險大)

(2)設置萬能碼

去掉驗證碼的主要是安全問題,為了應對在線系統的安全性威脅,可以在修改程式時不取消驗證碼,而是程式中留一個「後門」,設置一個「萬能驗證碼」,只要用戶輸入這個「萬能驗證碼」,程式就認為驗證通過,否則按照原先的驗證方式進行驗證。

(3)驗證碼識別技術

例如可以通過Python-tesseract 來識別圖片驗證碼,Python-tesseract 是光學字元識別Tesseract CR 引擎的Python 封裝類。能夠讀取任何常規的圖片文件(JPGGIFPNG等)。不過,目前市面上的驗證碼形式繁多,目前任何一種驗證碼識別技術,識別率都不是100% 。(玩玩還行,工作中不推薦)

(4)記錄Cookie

通過向瀏覽器中添加Cookie可以繞過登錄的驗證碼,這是比較有意思的一種解決方案。我們可以在用戶登錄之前,通過add_cookie()方法將用戶名密碼寫入瀏覽器Cookie,再次訪問系統登錄鏈接將自動登錄。

3、Selenium繞過驗證碼進行登陸

提示:使用上面第4種方式進行實現。

"""
1.學習目標
    掌握驗證碼處理方式
2.操作步驟
    2.1 獲取登錄後的cookie
        通過瀏覽器F12或抓包工具
    2.2 將登錄後的cookie添加到腳本中
        driver.add_cookie(字典格式)
    2.3 執行刷新操作
        driver.refresh()
3.需求
    獲取百度登錄後的cookie,實現免登陸
4.總結
    4.1 首先登錄一次
    4.2 明確哪些cookie和登錄相關
        (1)如果明確哪些cookie是保存用戶資訊,添加相應的cookie就好
        (2)如果不知道哪些cookie是保存用戶資訊的
            @1 可以把登陸後的cookie全部添加進去。
            @2也可以登陸前和登陸後分別獲取cookie,
            登陸後多出來的cookie就是和登陸相關的用戶資訊cookie。
    4.3 使用cookie做免登陸時,注意原來登錄的帳號不能退出。
"""
# 1.導入selenium
from selenium import webdriver
from time import sleep

# 2.打開瀏覽器
driver = webdriver.Chrome()

# 3.打開頁面
url = "//www.baidu.com/"
driver.get(url)
sleep(2)

"""
4. 登陸一次百度網站
    通過瀏覽器F12或抓包工具,獲取cookie,
    火狐瀏覽器方便獲取
"""

"""
5. 添加百度登錄後的cookie  
    要確定哪些cookie是和用戶資訊先關的。
    百度中BAIDUID和BDUSS兩個cookie是和用戶資訊相關的。
    這兩個cookie就可以實現百度免登錄。

    測公司自己項目的時候,需要用cookie實現免登錄,
    需要問一下開發,和用戶個人資訊相關的登陸數據是哪些cookie。
    載入這些條cookie資訊就可以實現免登錄。
"""
cookies = [{"name": "BAIDUID", "value": "026CB67282F2B6C4F2AC6880EAEFE5A6:FG=1"},
           {"name": "BDUSS",
            "value": "pJckQ3aXdEVi1ZaUVpalpDfjhmQTlpZW9mfnNCMUFCdDFCNUpZajB3TG5sdlJlRVFBQUFBJCQAAAAAAAAAAAEAAAAzO-pLc2RqYWtzZGs3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOcJzV7nCc1eYX"}]

# 6. 遍歷cookies列表,添加cookie
for cookie in cookies:
    driver.add_cookie(cookie)

# 7. 刷新頁面
driver.refresh()
sleep(3)

# 8.關閉瀏覽器
driver.quit()

"""
注意:
當你手動點擊退出登陸,你所載入這這些cookie就失效了。
如果還需要通過cookie實現免登錄,就要重新獲取cookie資訊。
"""

4、Selenium繞過驗證碼進行登陸補充示例

通過比對登陸操作前後Cookie的變化,來確定與用戶登陸操作相關的Cookie資訊。

提示:下面程式碼是提供一個解決問題的思路,以後在實際工作中按自己的需求自行封裝。

程式碼如下:

# 導入包
from selenium import webdriver
import time

# 定義全局變數
url = '//www.baidu.com/'


# 登陸操作
def login():
    '''先定義一個正常登錄的方法,獲取登錄前和登錄後的cookie'''

    driver = webdriver.Chrome()

    driver.get(url)
    driver.maximize_window()
    cookieBefore = driver.get_cookies() # 獲取所有cookie
    # 列印登錄前的所有cookie
    print(cookieBefore)
    time.sleep(2)
    driver.find_element_by_id("new-username").clear()
    driver.find_element_by_id("new-username").send_keys("username")
    driver.implicitly_wait(5)
    driver.find_element_by_id("new-password").clear()
    driver.find_element_by_id("new-password").send_keys("password")
    driver.find_element_by_id('home-right-login').click()
    driver.implicitly_wait(5)
    # 加一個休眠,這樣得到的cookie 才是登錄後的cookie,否則可能列印的還是登錄前的cookie
    time.sleep(5)
    print("登錄後!")
    cookiesAfter = driver.get_cookies() # 獲取登陸後的所有cookie
    print("cookiesAfter:")
    print(cookiesAfter)
    # cookie 存放到了list,其中是dict
    # 對比發現登錄後的cookie比登錄前多了4個dict。
    # 如下程式碼分別是  1、4 、7、 8
    len1 = len(cookiesAfter)

    # 以下程式碼被寫死不能通用
    print("len:%d" %len1)
    cookie1 = cookiesAfter[0]
    cookie2 = cookiesAfter[3]
    cookie3 = cookiesAfter[-2]
    cookie4 = cookiesAfter[-1]
    print("cookie1:%s" %cookie1)
    print("cookie2:%s" %cookie2)
    print("cookie3:%s" %cookie3)
    print("cookie4:%s" %cookie4)
    driver.quit()
    # 將獲取的這四個cookie作為參數,傳遞給,使用cookie登錄的函數,如下
    cookieLogin(cookie1,cookie2,cookie3,cookie4)


# 使用cookie免登錄操作
def cookieLogin(cookie1,cookie2,cookie3,cookie4):
    print("+++++++++++++++++++++++++")
    print("cookieLogin")
    print("cookie2:%s" % cookie2)
    print("cookie4:%s" % cookie4)
    driver = webdriver.Chrome()
    driver.maximize_window()
    # 清除一下cookie
    driver.delete_all_cookies()
    time.sleep(3)
    driver.get(url)
    # 打開瀏覽器後添加訪問地址後,添加cookie
    driver.add_cookie(cookie1)
    driver.add_cookie(cookie2)
    driver.add_cookie(cookie3)
    driver.add_cookie(cookie4)
    print("cookies")
    # 列印一下cookie,與上面正常登錄的cookie對比一下
    print(driver.get_cookies())
    time.sleep(5)
    # 刷新頁面,可以看到已經是登錄狀態了,至此完成的使用cookie 的登錄。
    driver.refresh()
    time.sleep(5)
    driver.quit()


if __name__ == "__main__":
    login()

5、總結

  • 通過上面例子我們可以知道,查看訪問百度所獲得的Cookie中,也沒有看到有「sessionID」的數據,所以說「sessionID」名字是其他的名字也是一樣的,後端拿到這些Cookie之後,只需要知道這個數據就是Session,然後拿去和資料庫里的進行比對就行了。
  • 使用Cookie進行登錄最大的難點是如何獲得與用戶登陸或認證相關的Cookie資訊 ,如果找到不到對應Cookie的名字,就沒辦法通過add_cookie()方法設置有效的Cookie資訊。
    可以通過get_cookies()方法來獲取登錄的所有的Cookie資訊,從而通過add_cookie()方法將用戶登陸或認證相關的Cookie數據,寫入到瀏覽器Cookie中。
    也可以通過登陸前和登陸後分別獲取Cookie,登陸後多出來的Cookie就是和登陸相關的用戶資訊Cookie
    當然最簡單的方法還是在介面文檔中有明確的說明,或者詢問開發人員。

參考://www.cnblogs.com/BlueSkyyj/p/8615879.html