請啟用 JavaScript 來查看內容

Playwright 瀏覽器自動化工具,應用於網路爬蟲和測試

前言

你還在使用 Selenium 來網路爬蟲或自動化測試嗎?或許你可以來試試另一個工具 — Playwright。

(圖片來源:Unsplash)
(圖片來源:Unsplash)

Playwright 套件簡介

Playwright 是微軟 Microsoft 開發的一個開源瀏覽器自動化工具,可以選擇 Chromium、Firefox、WebKit 瀏覽器,目前有 Python、JavaScript、TypeScript、.NET、Java 的 API 可供使用。

* 本篇文章以 Python 為範例,但各程式語言的 API 應該是差不多的。

LinuxmacOSWindows
Chromium 98.0.4708.0
WebKit 15.4
Firefox 94.0.1

* 此版本會持續更新,以官方文檔為主。


Playwright 第一次輸入指令就會自動下載瀏覽器,與自己使用的瀏覽器是分開的。不用像 Selenium 要手動下載,版本更新還要去更新驅動。


Playwright 在對元素(elements)操作之前,會自動等待元素準備完成(可見的、啟用的…),不用怕元素還沒載入就執行造成錯誤,也不需要自己加等待。

就像省去了 Selenium 內的 WebDriverWait:

1
2
3
WebDriverWait(self.driver, timeout).until(
    EC.presence_of_element_located((By.CSS_SELECTOR, '#search'))
)

* 詳細可以參考官方文檔:https://playwright.dev/python/docs/actionability


* Playwright 支援同步和異步(搭配 asyncio),本篇文章皆使用同步來示範。
* Playwright 甚至能自動產生程式碼,這部分可以參考大數學堂的影片教學:[爬蟲實戰] 如何不寫任何一行程式碼透過低代碼Low-Code / No-Code 工具 Playwright撰寫網頁自動化瀏覽程式



教學

先來試試官方文檔內的基本程式:

1
2
3
4
5
6
7
8
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch()
    page = browser.new_page()
    page.goto("http://playwright.dev")
    print(page.title())
    browser.close()

首先創造一個瀏覽器實例,開新分頁,再來前往 http://playwright.dev 網頁,並取得網頁的 title,最後關閉瀏覽器。


它預設是以「無頭模式」啟動,但為了在寫程式時觀察它運作,我們可以先將其關閉:

1
browser = p.chromium.launch(headless=False)

常見的基本操作

以下是幾種常見的網頁基本操作:

1
2
3
4
5
6
7
8
# 點擊
page.click('div')
# 輸入文字
page.fill('#search', 'query')
# 複選框和單選按鈕
page.check('#agree')
# 下拉選擇欄
page.select_option('select#colors', 'blue')

更多進階用法與參數可參考官方文檔:


元素定位

基本操作或取得元素皆使用 CSS Selector 元素定位。


Playwright 除了有一般的 Selector 用法以外,還有個比較特別且好用的 "文字(text)" 選擇方式:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# 取得包含此段文字的元素 (不分大小寫)
page.click('text=Log in')
# 取得與此段文字一模一樣的元素 (注意裡面還有引號)
page.click('text="Log in"')

# 如果要與 CSS Selector 結合,要使用以下方式
# 概念同等於上方的 'text=Log in',包含此段文字 (不分大小寫)
page.click('button:text("Log in")')
# 概念同等於上方的 'text="Log in"',文字要完全一樣
page.click('button:text-is("Log in")')

# 使用正則表達式
page.click('button:text-matches("[+-]?\\d+")')

# 還有一種是匹配內部包含文字的任何元素,可能在子元素或後代元素中
# 例如底下會匹配 <article><div>Playwright</div></article>。
element = page.wait_for_selector('article:has-text("Playwright")')

在文字匹配會對空格進行正規化,例如將多個空格轉換為一個,將換行符變成空格並忽略開頭和結尾的空格。

因為這部分有多種狀況、較複雜,我只是初步嘗試,如有錯誤歡迎底下留言告知。
參考:https://playwright.dev/python/docs/selectors/#text-selector


以及一些其他的選擇方式:

1
2
3
4
# 返回 <article> 具有 <div class=promo> 內部元素的文本內容
page.text_content("article:has(div.promo)")
# 僅點擊可見 class=button 的元素
page.click(".button:visible")

選取元素

如果要取得元素,可以使用:

1
2
3
4
# 取得元素
page.query_selector('#promo')
# 取得元素,加入等待
page.wait_for_selector('#promo')

獲取元素的文字及屬性:

1
2
3
4
# 取得元素的文字
page.query_selector('h3').text_content()
# 取得元素的屬性(attribute)
page.query_selector('section').get_attribute('class')

瀏覽器參數

在教學一開始說到無頭模式,在 launch 加入 headless=False,它還有其他參數可以設定。
詳見:https://playwright.dev/python/docs/api/class-browsertype#browser-type-launch

像是傳遞給瀏覽器實例的附加參數,想讓它靜音就使用:

1
2
3
browser = playwright.chromium.launch(
    args=["--mute-audio"]  # 靜音
)

更多 Chromium flags 的列表:https://peter.sh/experiments/chromium-command-line-switches/


Cookies 和 Local Storage

儲存與載入 Cookies 和 Local Storage,可以用作保存登入狀態。

1
2
3
4
5
# 將存儲狀態保存到文件中
storage = context.storage_state(path="state.json")

# 使用保存的存儲狀態創建新上下文(context)
context = browser.new_context(storage_state="state.json")

結語

它還有個 GUI 工具 Trace Viewer,可以在程式執行後幫助探索操作過程,感覺非常的厲害,但這部分我就還沒嘗試過,有興趣可以參考:https://playwright.dev/python/docs/trace-viewer


Playwright 相比 Selenium 來說是比較新出來的工具(不過都已經是正式版了),許多功能更好用,如果你原先是使用 Selenium 來寫網路爬蟲或做自動化測試,或許可以試試 Playwright,搞不好你就會愛上囉。😆


歡迎追蹤『IT空間』FB 粉專,取得最新發文通知🔔




參考:
Playwright 官方網站
Playwright 文檔
Playwright API
Playwright for Python GitHub


對於自己想做的事,就放手去挑戰吧!不是因為覺得能成功就去做,而是發自內心的想要嘗試看看,這樣不管結果如何,自己都不會後悔。

—— 鈴木一朗 (棒球選手)


🔻 如果覺得喜歡,歡迎在下方獎勵我 5 個讚~
分享

Jia
作者
Jia
軟體工程師 - Software Engineer