推薦一款新的自動化測試框架:DrissionPage!

2023-02-21 12:02:15

今天給大家推薦一款基於Python的網頁自動化工具:DrissionPage。這款工具既能控制瀏覽器,也能收發封包,甚至能把兩者合而為一,簡單來說:集合了WEB瀏覽器自動化的便利性和 requests 的高效率。

一、DrissionPage產生背景

實現網頁自動化,會有兩類形式:

  • 直接向伺服器傳送請求封包,獲取需要的資料
  • 模擬真實使用者操作行為,控制瀏覽器跟網頁進行互動

前者輕量級,速度快,例如requests 庫。但requests面對需要登入的網站時,往往還要應付驗證碼、JS 混淆、簽名引數等反爬手段,門檻較高。若資料是由 JS 計算生成的,還須重現計算過程,開發效率不高。

而後者直接使用瀏覽器,模擬使用者行為,如Selenium庫,可以很大程度上繞過這些坑,但瀏覽器執行效率不高。

因此,DrissionPag設計初衷,是將它們合而為一,能夠在不同須要時切換相應模式,並提供一種人性化的使用方法,提高開發和執行效率。

為什麼叫DrissionPag

Selenium框架用於操作瀏覽器的物件叫 Driver,requests 用於管理請求連線的物件叫 Session,因此Drission 就是它們兩者的合體。在舊版本中,是通過對 selenium 和 requests 的重新封裝實現的。

但從 3.0 版開始,作者另起爐灶,用 chromium 協定自行實現了 selenium 全部功能,從而擺脫了對 selenium 的依賴,功能更多更強,執行效率更高,開發更靈活。

二、DrissionPage亮點特色

本庫採用全自研的核心,對比 selenium,有以下優點:

  • 無 webdriver 特徵,不會被網站識別,無需為不同版本的瀏覽器下載不同的驅動
  • 執行速度更快,可以跨 iframe 查詢元素,無需切入切出,iframe 看作普通元素,獲取後可直接在其中查詢元素,邏輯更清晰
  • 可以同時操作瀏覽器中的多個分頁,即使分頁為非啟用狀態,無需切換
  • 內建等待和自動重試功能。使不穩定的網路變得易於控制,程式更穩定,編寫更省心
  • 允許反覆使用已經開啟的瀏覽器。無須每次執行從頭啟動瀏覽器,偵錯超方便
  • 極簡的語法規則。整合大量常用功能,定位元素更加容易,功能更強大穩定
  • 使用 POM 模式封裝,可直接用於測試,便於擴充套件
  • 等等。。。

三、安裝搭建

說了這麼多,相信很多人已經躍躍欲試了,怎麼快速搭建這套框架,先要準備一些基礎環境。

環境準備

  • 作業系統:Windows、Linux 或 Mac。
  • python 版本:3.6 及以上
  • 支援瀏覽器:Chromium 核心(如 Chrome 和 Edge)

專案地址:

https://gitee.com/g1879/DrissionPage

使用 pip 安裝 DrissionPage:

pip install DrissionPage

另外在開始之前,我們先進行一些簡單設定。如果只使用收發封包功能,無須任何準備工作。

如果要控制瀏覽器,須設定瀏覽器路徑。程式預設設定控制 Chrome,所以以下用 Chrome 作為演示。如果要使用 Edge 或其它 Chromium 核心瀏覽器,設定方法是一樣的。

設定瀏覽器路徑:

from DrissionPage.easy_set import set_paths
set_paths(browser_path=r'這裡修改為您的Chrome瀏覽器exe檔案路徑')

這段程式碼會記錄 Chrome 瀏覽器路徑到組態檔。由於路徑設定只要執行一次即可,不要寫到正式程式裡。一般建議新建一個臨時 py 檔案,並輸入以下程式碼,填入您電腦裡的 Chrome 瀏覽器 exe 檔案路徑,然後執行。

四、實戰一下

1、嘗試啟動瀏覽器:

from DrissionPage import ChromiumPage

page = ChromiumPage()
page.get('https://www.baidu.com')

執行以下程式碼,如果正常啟動了瀏覽器並且存取了百度,說明可直接使用,跳過後面的步驟即可。

執行程式碼前,如果已有開啟的 Chrome 瀏覽器,請關閉。

2、與selenium框架程式碼對比

#案例一:用顯性等待方式查詢第一個文字包含 some text 的元素。
# 使用 selenium:
element = WebDriverWait(driver).until(ec.presence_of_element_located((By.XPATH, '//*[contains(text(), "some text")]')))

# 使用 DrissionPage:
element = page('some text')

#案例二:跳轉到第一個分頁
# 使用 selenium:
driver.switch_to.window(driver.window_handles[0])

# 使用 DrissionPage:
page.to_tab(0)

# 案例三:拖拽一個元素
# 使用 selenium:
ActionChains(driver).drag_and_drop(ele1, ele2).perform()

# 使用 DrissionPage:
ele1.drag_to(ele2)

以上程式碼實現一模一樣的功能,但DrissionPage程式碼明顯更簡潔優雅。

3、與requests框架程式碼對比

# 案例一:獲取元素內容
url = 'https://baike.baidu.com/item/python'

# 使用 requests:
from lxml import etree
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36'}
response = requests.get(url, headers = headers)
html = etree.HTML(response.text)
element = html.xpath('//h1')[0]
title = element.text

# 使用 DrissionPage:
page = WebPage('s')
page.get(url)
title = page('tag:h1').text

4、DrissionPage不同模式切換

例如:用瀏覽器登入網站,然後切換到 requests 讀取網頁。兩者會共用登入資訊。

from DrissionPage import WebPage
from time import sleep

# 建立頁面物件,預設 d 模式
page = WebPage()  
# 存取個人中心頁面(未登入,重定向到登入頁面)
page.get('https://gitee.com/profile')  

# 使用 selenium 輸入賬號密碼登入
page.ele('@id:user_login').input('your_user_name')  
page.ele('@id:user_password').input('your_password\n')
sleep(1)

# 切換到 s 模式
page.change_mode()  
# 登入後 session 模式的輸出
print('登入後title:', page.title, '\n')  

五、小結

DrissionPage體驗一番後,雖然也發現了一些不足的地方,但整得來講,很多設計理念還是非常值得借鑑的,更多功能就留給大家去探索了,專案檔案地址:

http://g1879.gitee.io/drissionpagedocs/