一、如何使用代理方式開啟網頁
在 playwright.chromium.launch()
中傳入 proxy
引數即可,示例程式碼如下:
1、同步寫法:
from playwright.sync_api import sync_playwright
proxy = {'server': 'http:/127.0.0.1:8080'}
def run():
with sync_playwright() as p:
browser = p.chromium.launch(headless=False, proxy=proxy)
page = browser.new_page()
page.goto('https://www.baidu.com')
title = page.title()
if "百度" in title:
print("開啟百度成功")
else:
print("開啟百度失敗")
browser.close()
run()
2、非同步寫法:
from playwright.async_api import async_playwright
import asyncio
proxy = {'server': 'http:/127.0.0.1:8080'}
async def run():
async with async_playwright() as p:
browser = await p.chromium.launch(headless=False, proxy=proxy)
page = await browser.new_page()
await page.goto('https://www.baidu.com')
title = await page.title()
if "百度" in title:
print("開啟百度成功")
else:
print("開啟百度失敗")
await browser.close()
asyncio.get_event_loop().run_until_complete(run())
二、同步和非同步寫法對比
1、同步的優點:
- 程式碼結構簡單易懂,不需要學習
async/await
語法 - 適用於小規模或簡單任務
- 除錯和理解同步程式碼更簡單
2、非同步的優點:
- 能更高效地利用系統資源,避免阻塞等待IO
- 對於長時間操作如網路請求更高效
- 可以支援併發執行多個任務
- 對於大規模和複雜系統更有利
3、區別
- 對於小任務和學習用途,同步程式碼結構更簡單。
- 對於需要長時間IO等待的任務(如網路請求),使用非同步可以更高效。
- 對於需要支援高併發的系統(如網站),使用非同步模型可以支援更多併發連線。
- 多執行緒同步會帶來鎖的問題,而非同步避免了鎖的使用。
- 非同步的FUTURE模式也更易於擴充套件性好,支援動態增加回撥函式。
4、總結
- 小任務用同步
- 長時間IO任務用非同步
- 高併發系統用非同步
- 以後的功能擴充套件考慮非同步更靈活
一般來說對於現代化系統,非同步程式設計模型將是主流趨勢。但同步在某些場景也同樣易用。選擇時要根據具體需求來權衡。
三、寫一個用例
1、示例指令碼
算是個入門的例子,關於每句話的意思,看我註釋即可,示例程式碼如下:
import re
from playwright.sync_api import Page, expect, sync_playwright
proxy = {'server': 'http://127.0.0.1:8080'}
def test_baidu():
with sync_playwright() as p:
browser = p.chromium.launch(headless=False, proxy=proxy)
page = browser.new_page()
# 跳轉到baidu頁面
page.goto("https://www.baidu.com/")
# 點選輸入框
page.locator("#kw").click()
# 輸入框輸入selenium
page.locator("#kw").fill("selenium")
# 點選百度一下查詢按鈕
page.get_by_role("button", name="百度一下").click()
# 驗證輸入框是否輸入selenium
expect(page.locator("#kw")).to_have_value("selenium")
# 驗證頁面是否包含文字“大家還在搜”
expect(page.locator("#content_left")).to_contain_text("大家還在搜")
# 退出瀏覽器
browser.close()
注意:
測試類和測試方法都要用test_ 字首命名
2、基本操作
這是 Playwright 常用操作列表,請注意,還有許多其他操作,請務必檢視定位器 API 部分以瞭解更多相關資訊。
操作 | 描述 |
---|---|
locator.check() | 選中輸入核取方塊 |
locator.click() | 點選元素 |
locator.uncheck() | 取消選中輸入核取方塊 |
locator.hover() | 將滑鼠懸停在元素上 |
locator.fill() | 填寫表單欄位,輸入文字 |
locator.focus() | 聚焦元素 |
locator.press() | 按下單個鍵 |
locator.set_input_files() | 選擇要上傳的檔案 |
locator.select_option() | 從下拉選單中選擇選項 |
3、斷言操作
斷言 | 描述 |
---|---|
expect(locator).to_be_checked() | 核取方塊處於選中狀態 |
expect(locator).to_be_enabled() | 控制元件已啟用 |
expect(locator).to_be_visible() | 元素可見 |
expect(locator).to_contain_text() | 元素包含文字 |
expect(locator).to_have_attribute() | 元素具有屬性 |
expect(locator).to_have_count() | 元素列表已給出長度 |
expect(locator).to_have_text() | 元素匹配文字 |
expect(locator).to_have_value() | 輸入元素具有值 |
expect(page).to_have_title() | 頁面有標題 |
expect(page).to_have_url() | 頁面有 URL |
4、fixtures夾具的使用
示例程式碼:
import pytest
from playwright.sync_api import Page, expect, sync_playwright
@pytest.fixture(scope="function", autouse=True)
def before_each_after_each(page: Page):
print("before the test runs")
page.goto("https://www.baidu.com/")
yield
print("after the test runs")
def test_main_navigation(page: Page):
page.locator("#kw").fill("久曲健 部落格園")
page.get_by_role("button", name="百度一下").click()
expect(page.locator("#content_left")).to_contain_text("久曲健 - 部落格園")
程式碼解釋:
- 定義了一個名為 before_each_after_each 的 fixture(夾具),它的作用域是每個測試函式,並且設定為自動應用於每個測試函式。
- 在這個 fixture 中: 列印 "before the test runs",表示測試執行前執行的操作。 使用 page.goto("https://www.baidu.com/") 開啟百度首頁。
- yield 關鍵字在這個 fixture 執行期間掛起,等待測試函式執行。測試函式將在 fixture 的環境下執行。