『心善淵』Selenium3.0基礎 — 21、Selenium實現繞過驗證碼進行登陸
- 2021 年 7 月 9 日
- 筆記
- 測試基礎必會技能 - Selenium測試框架
1、驗證碼問題說明
對於Web應用來說,大部分的系統在用戶登錄時,都要求用戶輸入驗證碼。驗證碼的類型的很多,有字母數字的,有漢字的,甚至還要用戶輸入一條算術題的答案的。對於系統來說,使用驗證碼可以有效果的防止採用機器猜測方法對口令的刺探,在一定程度上增加了安全性。但對於測試人員來說,不管是進行性能測試,還是自動化測試都是一個棘手的問題。
2、處理驗證碼的方法
(1)去掉驗證碼
這是最簡單的方法,對於開發人員來說,只是把驗證碼的相關程式碼注釋掉即可,如果是在測試環境,這樣做可省去了測試人員不少麻煩,如果自動化腳本是要在正式環境跑,這樣就給系統帶來了一定的風險。(風險大)
(2)設置萬能碼
去掉驗證碼的主要是安全問題,為了應對在線系統的安全性威脅,可以在修改程式時不取消驗證碼,而是程式中留一個「後門」,設置一個「萬能驗證碼」,只要用戶輸入這個「萬能驗證碼」,程式就認為驗證通過,否則按照原先的驗證方式進行驗證。
(3)驗證碼識別技術
例如可以通過Python-tesseract
來識別圖片驗證碼,Python-tesseract
是光學字元識別Tesseract CR
引擎的Python 封裝類。能夠讀取任何常規的圖片文件(JPG
、 GIF
、PNG
等)。不過,目前市面上的驗證碼形式繁多,目前任何一種驗證碼識別技術,識別率都不是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
。
當然最簡單的方法還是在介面文檔中有明確的說明,或者詢問開發人員。