Files
tool-notes/playwright-notes.md
Timmy f3f832df20 初始提交:工具安裝與使用筆記
包含 MemPalace、MarkItDown、Playwright 的安裝與使用筆記。

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 09:29:01 +08:00

5.4 KiB
Raw Permalink Blame History

Playwright (Python) 安裝與使用筆記

基本資訊

安裝

pip install playwright        # 安裝 Python 套件
playwright install            # 下載瀏覽器Chromium、Firefox、WebKit
playwright install chromium   # 只裝特定瀏覽器

已安裝的瀏覽器

瀏覽器 版本 路徑
Chromium ~/Library/Caches/ms-playwright/
Firefox 135.0 ~/Library/Caches/ms-playwright/firefox-1475
WebKit 18.4 ~/Library/Caches/ms-playwright/webkit-2140

同步 API

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch()          # 無頭模式
    # browser = p.chromium.launch(headless=False)  # 有頭模式(看得到瀏覽器)
    page = browser.new_page()
    page.goto("https://example.com")
    print(page.title())
    page.screenshot(path="screenshot.png")
    browser.close()

非同步 API

import asyncio
from playwright.async_api import async_playwright

async def main():
    async with async_playwright() as p:
        browser = await p.chromium.launch()
        page = await browser.new_page()
        await page.goto("https://example.com")
        print(await page.title())
        await page.screenshot(path="screenshot.png")
        await browser.close()

asyncio.run(main())

常用操作

選取元素與互動

# 點擊
page.click("text=登入")
page.click("#submit-btn")
page.click("button.primary")

# 填寫表單
page.fill("#username", "user@example.com")
page.fill("#password", "secret")

# 選擇下拉選單
page.select_option("select#color", "blue")

# 勾選 checkbox
page.check("#agree")

# 等待元素出現
page.wait_for_selector(".result")

# 取得文字內容
text = page.text_content(".message")
inner = page.inner_text("h1")

截圖與 PDF

# 截圖
page.screenshot(path="page.png")
page.screenshot(path="full.png", full_page=True)

# 特定元素截圖
page.locator(".card").screenshot(path="card.png")

# 存成 PDF僅 Chromium 支援)
page.pdf(path="page.pdf")

Locator推薦的選取方式

# 依角色
page.get_by_role("button", name="送出")

# 依文字
page.get_by_text("歡迎光臨")

# 依 label
page.get_by_label("電子郵件")

# 依 placeholder
page.get_by_placeholder("搜尋...")

# 依 test id
page.get_by_test_id("login-form")

# 鏈式操作
page.locator(".card").filter(has_text="特價").first.click()

網路攔截

# 攔截請求
def handle_route(route):
    if "analytics" in route.request.url:
        route.abort()
    else:
        route.continue_()

page.route("**/*", handle_route)

# 攔截並修改回應
def mock_api(route):
    route.fulfill(
        status=200,
        content_type="application/json",
        body='{"data": "mocked"}'
    )

page.route("**/api/data", mock_api)

Browser Context隔離環境

# 每個 context 有獨立的 cookies、localStorage
context = browser.new_context(
    viewport={"width": 1280, "height": 720},
    locale="zh-TW",
    timezone_id="Asia/Taipei",
    user_agent="custom-agent",
)
page = context.new_page()

# 帶裝置模擬
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    iphone = p.devices["iPhone 14"]
    context = browser.new_context(**iphone)

等待與自動等待

# Playwright 預設自動等待元素可操作後才執行動作
# 以下是額外的等待方法:

page.wait_for_load_state("networkidle")   # 等網路閒置
page.wait_for_url("**/dashboard")         # 等 URL 變化
page.wait_for_selector(".loaded")         # 等元素出現

# 等待 response
with page.expect_response("**/api/data") as response_info:
    page.click("#load-btn")
response = response_info.value

CLI 工具

Codegen自動產生程式碼

# 打開瀏覽器錄製操作,自動產生 Python 程式碼
playwright codegen https://example.com

# 指定裝置模擬
playwright codegen --device="iPhone 14" https://example.com

# 指定語言
playwright codegen --target python-async https://example.com

Trace Viewer除錯追蹤

# 錄製 trace
context.tracing.start(screenshots=True, snapshots=True, sources=True)

# ... 執行操作 ...

context.tracing.stop(path="trace.zip")
# 檢視 trace
playwright show-trace trace.zip

其他 CLI

playwright open https://example.com       # 開啟瀏覽器
playwright screenshot --help              # 截圖工具
playwright install --with-deps            # 安裝瀏覽器 + 系統相依

Pytest 整合

pip install pytest-playwright
# test_example.py
def test_homepage(page):
    page.goto("https://example.com")
    assert page.title() == "Example Domain"

def test_login(page):
    page.goto("https://example.com/login")
    page.fill("#username", "admin")
    page.fill("#password", "password")
    page.click("text=Login")
    assert page.url == "https://example.com/dashboard"
# 執行測試
pytest
pytest --headed                   # 顯示瀏覽器
pytest --browser firefox          # 指定瀏覽器
pytest --browser chromium --browser firefox  # 多瀏覽器