1.簡介
通過前邊的講解和學習,細心認真地你可能發現在Playwright中,沒有Element這個概念,只有Page的概念,Page不僅僅指的是某個頁面,例如頁面間的跳轉等,還包含了所有元素、事件的概念,所以我們包括定位元素、頁面轉向,都是基于Page操作的。頁面提供了與瀏覽器中的單個選項卡或 Chromium 中的擴展后臺頁面進行交互的方法。一個瀏覽器實例可能有多個?Page?實例。
2.Browser、Context 和Page的關系
第一次接觸Playwright的同學,一定會對Browser、Context 和Page這三個概念所困擾,不知道這三者有怎樣的聯系,接下來就帶大家梳理一下,一張圖秒懂!
2.1Browser
對應一個瀏覽器實例(Chromium、Firefox或WebKit),Playwright腳本以啟動瀏覽器實例開始,以關閉瀏覽器結束。瀏覽器實例可以在headless或者 headful模式下啟動。一個 Browser 可以包含多個 BrowserContext。一個Browser是一個Chromium, Firefox 或 WebKit(plarywright支持的三種瀏覽器)的實例plarywright腳本通常以啟動瀏覽器實例開始,以關閉瀏覽器結束。瀏覽器實例可以在headless(沒有 GUI)或head模式下啟動。
啟動browser實例是比較耗費資源的,plarywright做的就是如何通過一個browser實例最大化多個BrowserContext的性能。
2.2BrowserContext
Playwright為每個測試創建一個瀏覽器上下文,即BrowserContext,瀏覽器上下文相當于一個全新的瀏覽器配置文件,提供了完全的測試隔離,并且零開銷。創建一個新的瀏覽器上下文只需要幾毫秒,每個上下文都有自己的Cookie、瀏覽器存儲和瀏覽歷史記錄。瀏覽器上下文允許同時打開多個頁面并與之交互,每個頁面都有自己單獨的狀態,一個 BrowserContext 可以包含多個 Page。一個BrowserContex就像是一個獨立的匿名模式會話(session),非常輕量,但是又完全隔離。
每個browser實例可有多個BrowserContex,且完全隔離。比如可以在兩個BrowserContext中登錄兩個不同的賬號,也可以在兩個 context 中使用不同的代理。
context還可用于模擬涉及移動設備、權限、區域設置和配色方案的多頁面場景。
2.3Page
頁面指的是瀏覽器上下文中的單個選項卡或彈出窗口。在Page中主要完成與頁面元素交互,一個 Page 可以包含多個 Frame。
2.4Frame
每個頁面有一個主框架(page.MainFrame()),也可以有多個子框架,由 iframe 標簽創建產生。在playwright中,無需切換iframe,可以直接定位元素(這點要比selenium方便很多)。接下來我們著重來看一下page。
3.訪問一個URL
page.goto("https://example.com")
4.截圖
page.screenshot(path="screenshot.png")
5.監聽Iframe加載(監聽頁面事件)
page.on("frameattached", handler)
6.定位到含有指定文字的元素
返回一個Locator:
page.get_by_text("test") # 模糊匹配
page.get_by_text("test", exact=True) # 精準匹配
7.返回上一頁
page.go_back()
page.go_back(**kwargs)
8.前往下一頁
page.go_forward()
page.go_forward(**kwargs)
9.根據選擇器定位元素(CSS\Xpath)
page.locator(selector)
page.locator(selector, **kwargs)
10.項目實戰
以百度為例,首先啟動瀏覽器,然后再設置瀏覽器的大小。查詢“程序員的世界你不懂”后,刷新頁面執行回退到百度首頁,然后有執行前進進入到搜索“程序員的世界你不懂”頁面,最后退出瀏覽器。
10.1代碼設計
按照上邊的步驟進行代碼設計,如下所示:
10.2參考代碼
# coding=utf-8from playwright.sync_api import sync_playwrightwith sync_playwright() as p :# 1.啟動瀏覽器browser = p.chromium.launch(headless=False)# 2.設置瀏覽器窗口大小context = browser.new_context(viewport={'width': 1920, 'height': 1080},)page = context.new_page()# 3.訪問度娘page.goto("https://www.baidu.com")# 等待5秒page.wait_for_timeout(5000)# 4.輸入“程序員的世界你不懂”,點擊“百度一下”page.fill("input[name=\"wd\"]", "程序員的世界你不懂")page.click("text=百度一下")# 等待5秒page.wait_for_timeout(5000)# 5.刷新頁面page.reload()# 等待5秒page.wait_for_timeout(5000)# 6.瀏覽器后退page.go_back()# 等待5秒page.wait_for_timeout(5000)# 7.瀏覽器前進page.go_forward()# 8.瀏覽器退出page.wait_for_timeout(5000)context.close()browser.close()
10.3運行代碼
1.運行代碼,右鍵Run'Test',控制臺輸出,如下圖所示:
2.運行代碼后電腦端的瀏覽器的動作,可以看到查詢“程序員的世界你不懂”后,刷新頁面執行回退到百度首頁,然后有執行前進進入到搜索“程序員的世界你不懂”頁面。
11.小結
11.1browser,context和page三層結構
browser,context和page這三層結構個人淺見:
(1)Browser可以理解為物理層,比較常用的參數為瀏覽器類型,headless(是否在內存中打開瀏覽器)以及超時時間。
(2)Context為上下文層,常用的參數為設置窗口大小以及錄像路徑。
(3)page為頁面層,就是為了打開“可見”的頁面,只有這一層才是真的訪問了頁面。