【Playwright + Python】系列(十七)揭秘 Playwright 處理 Handles:開啟高效自動化之門
哈嘍,大家好,我是六哥!今天來跟大家聊一聊Playwright 處理 Handles的方法,面向對象為功能測試及零基礎小白,這里我盡量用大白話的方式舉例講解,力求所有人都能看懂,建議大家先收藏,以免后面找不到。??
一、什么是Handles
在 Playwright 中,Handles 是一種特殊的數據結構,用于在 Playwright 的進程與瀏覽器環境之間建立橋梁,使你能夠從 Playwright 的環境中訪問和操作瀏覽器內的對象。簡單來說,Handles 讓你能夠“抓住”頁面上的元素或 JavaScript 對象,并對其進行操作。
二、為什么需要 Handles?
跨環境操作:由于 Playwright 運行在一個進程中,而瀏覽器中的 JavaScript 代碼運行在另一個進程中,Handles 提供了一種機制,使得這兩個環境之間的對象可以相互操作。
保持對象引用:通過 Handles,你可以在 Playwright 中保留對瀏覽器內對象的引用,即使這些對象在瀏覽器環境中發生了變化,只要 Handles 沒有被銷毀,你依然可以通過它們訪問到這些對象。
延遲執行:使用 Handles 可以延遲執行某些操作,直到特定條件滿足為止,例如等待某個元素出現在頁面上。
三、兩種主要類型的 Handles
1、JSHandle
用途:引用頁面中的任何 JavaScript 對象。
特點:JSHandle 可以表示任何類型的 JavaScript 對象,比如數組、函數、DOM 元素等。它提供了一種方式,讓你可以在 Playwright 的上下文中操作這些對象。
生命周期:除非頁面導航或顯式地調用了 dispose() 方法,否則 JSHandle 會一直存在,防止對應的 JavaScript 對象被垃圾回收。
2、ElementHandle
用途:專門用于引用頁面中的 DOM 元素,并且提供了額外的方法來對這些元素執行操作或斷言其屬性。
特點:ElementHandle 繼承自 JSHandle,因此具備所有 JSHandle 的功能。此外,它還提供了一些額外的方法,如點擊、填寫文本、獲取元素的邊界框等,這些方法可以直接作用于 DOM 元素上。
生命周期:同 JSHandle 一樣,除非頁面導航或顯式地調用了 dispose() 方法,否則 ElementHandle 會一直存在。
四、實際應用示例
假設我們要在百度頁面上進行一些操作,我們可以使用 Handles 來實現:
1、獲取 JSHandle 示例
示例代碼
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(headless=False)
page = browser.new_page()
page.goto("https://www.baidu.com")
# 獲取 window 對象的 JSHandle
js_handle = page.evaluate_handle('window')
# 使用 jsHandle 進行評估
title = page.evaluate('window => window.document.title', js_handle)
# 斷言標題
assert title == "百度一下,你就知道"
print(f"Page Title: {title}")
2、獲取 ElementHandle 示例
示例代碼
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(headless=False)
page = browser.new_page()
page.goto("https://www.baidu.com")
# 獲取搜索框的 ElementHandle
search_box_handle = page.wait_for_selector('#kw')
# 斷言搜索框的寬高
bounding_box = search_box_handle.bounding_box()
print(f"Search Box Bounding Box: {bounding_box}")
# 斷言搜索框的 maxlength 屬性
maxlength = search_box_handle.get_attribute('maxlength')
assert maxlength == '255'
browser.close()
3、將 Handle 作為參數傳遞
當需要在頁面上下文中操作由 Playwright 創建的對象時,可以將 Handle 傳遞給 evaluate 方法。
示例代碼
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(headless=False)
page = browser.new_page()
page.goto("https://www.baidu.com")
# 創建新的數組并返回數組的 JSHandle
my_array_handle = page.evaluate_handle("() => { return [1]; }")
# 獲取數組的長度
length = page.evaluate("array => array.length", my_array_handle)
print(f"Array Length: {length}")
# 向數組添加新元素
page.evaluate("(array, newElement) => array.push(newElement)", [my_array_handle, 2])
# 再次獲取數組的長度
new_length = page.evaluate("array => array.length", my_array_handle)
print(f"New Array Length: {new_length}")
# 釋放對象
my_array_handle.dispose()
browser.close()
4. 使用 Locator 而不是 ElementHandle
雖然 ElementHandle 仍然可用,但 Playwright 推薦使用 Locator 來執行用戶動作和斷言。這是因為 Locator 每次都會根據選擇器重新定位頁面上的元素,確保即使頁面狀態改變也能正確地找到元素。
示例
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(headless=False)
page = browser.new_page()
page.goto("https://www.baidu.com")
# 使用 Locator 定位搜索框
search_box_locator = page.locator('#kw')
# 輸入搜索詞
search_box_locator.fill('Playwright')
# 提交搜索
page.locator('#su').click()
# 驗證搜索結果
first_result = page.locator('h3 > a').first
print(first_result.text_content())
browser.close()
寫在最后
以上代碼展示了如何使用 Playwright 處理 Handles的使用方法。你可以根據自己的需求調整這些示例,感興趣的同學可以自行動手嘗試。 如需要全部源代碼,公眾號:軟件測試君,請回復“Playwright學習”獲取,無引號哦。
最后,希望大家都能順利掌握,一起進步。也歡迎分享給更多有需要的朋友哦!
若有收獲,就點個贊吧
優秀不夠,你是否無可替代
軟件測試交流QQ群:721256703,期待你的加入!!
歡迎關注我的微信公眾號:軟件測試君


浙公網安備 33010602011771號