1. 程式人生 > 實用技巧 >playwright-python 元素定位、frame處理

playwright-python 元素定位、frame處理

瀏覽器、Browser contexts、frame

Playwright 可以同時啟動多個瀏覽器(chromium、Firefox、webkit),每個瀏覽器可以啟動多個page(在Playwright上稱作Browser contexts

瀏覽器

啟動瀏覽器程式碼樣例:

from playwright import sync_playwright

with sync_playwright() as p:
    # 可以選擇chromium、firefox和webkit
    browser_type = p.chromium
    # 執行chrome瀏覽器,executablePath指定本地chrome安裝路徑
    # browser = browser_type.launch(headless=False,slowMo=50,executablePath=r"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe")
    browser = browser_type.launch(headless=False)
    page = browser.newPage()
    page.goto('https://www.baidu.com/')
    page.screenshot(path=f'example-{browser_type.name}.png')
    browser.close()
Browser contexts

同一個瀏覽器啟動多個page,可以模擬多頁面的場景:

from playwright import sync_playwright

with sync_playwright() as p:
    browser_type = p.chromium
    browser = browser_type.launch(headless=False)
    context = browser.newContext()
    page1 = context.newPage()
    page1.goto('https://mail.163.com/')
    page1.screenshot(path=f'page1-{browser_type.name}.png')
    page2 = context.newPage()
    page2.goto("https://www.baidu.com/")
    page2.screenshot(path=f'page2-{browser_type.name}.png')
    context.close()
    browser.close()

Browser contexts還可以模擬移動裝置:

from playwright import sync_playwright

with sync_playwright() as p:
    browser_type = p.chromium
    iphone_11 = p.devices['iPhone 11 Pro']
    browser = browser_type.launch(headless=False)
    context = browser.newContext(**iphone_11, permissions=['geolocation'], colorScheme='dark', locale='zh-CN')
    page = context.newPage()
    page.goto('https://mail.163.com/')
    page.screenshot(path=f'page2-{browser_type.name}.png')
    context.close()
    browser.close()
frame

處理frame,查詢frame有三種方法:

  1. framename屬性
  2. frameURL
  3. 通過其他的任何的selector
from playwright import sync_playwright

with sync_playwright() as p:
    browser_type = p.chromium
    browser = browser_type.launch(headless=False)
    page = browser.newPage()
    page.goto('https://mail.163.com/')
    # 通過selector、name、URL
    login_frame = page.querySelector("[id^='x-URS-iframe']").contentFrame()
    # login_frame = page.querySelector("#loginDiv>iframe").contentFrame()
    # login_frame2 = page.frame("name").contentFrame()
    # login_frame3 = page.frame("URL").contentFrame()
    # 檢視所有的frames
    print(page.frames)
    login_frame.fill("input[name='email']", "test123")
    login_frame.fill("input[name='password']", "1234")
    login_frame.click("#dologin")
    page.screenshot(path=f'example-{browser_type.name}.png')
    browser.close()

元素選擇器(元素查詢)

語法

Playwright可以使用CSS選擇器XPath選擇器HTML屬性(如id、data-test-id,甚至文字內容)來搜尋元素。只需直接使用即可,可以自動探測

簡寫
  1. 選擇器以// 或者..開頭,則會預設為是xpath=selector
    • 例子:page.click('//html') 可轉換為 page.click('xpath=//html')
  2. 選擇器開始和結束以引號("或者'),則預設為text=selector
    • 例子:page.click(' "foo" ') 可轉換為 page.click('text="foo"')
  3. 其他的預設為是css=selector
    • 例子:page.click('div') 可轉換為 page.click('css=div')
鏈式選擇器

選擇器可以與>>組合使用,例如selector1 >> selector2 >> selectors3。當選擇器被連結時,下一個選擇器會相對於前一個選擇器的結果進行查詢。

例如:

page.querySelector('css=article >> css=.bar > .baz >> css=span[attr=value]')

等同於:

page.querySelector('article').querySelector('.bar > .baz').querySelector('span[attr=value]')

css=article >> text=Hello查詢文字為Hello的 article 元素;*css=article >> text=Hello查詢包含文字Hello的 article 元素

最佳實踐

以下只是寫出了部分用法,詳情參考

  • 使用data-test-id

    page.click("data-test-id=login")
    
  • CSS 和 XPath

    page.click('div')
    page.click('//html/body/div')
    # 明確指定型別
    page.click('css=div')
    page.click('xpath=//html/body/div')
    # 點選#free-month-promo元素內文字為“Sign Up”的元素
    page.click('#free-month-promo >> text=Sign Up')
    
    page.fill('css=[placeholder="Search GitHub"]')
    page.fill('[placeholder="Search GitHub"]') # 簡寫
    
  • 通過文字子字串查詢

    page.click('text="Login"')
    page.click('"Login"'); # 簡寫
    
  • 獲取某元素內的所有文字

    print(page.evalOnSelector('.headerLogo', """e => e.textContent"""))
    print(page.querySelector('.headerLogo').textContent())
    
  • CSS 擴充套件 : visible

    # 點選第一個button
    page.click('button')
    # 點選第一個可視的button,如果有其他不可視的,則會忽略他們
    page.click('button:visible')
    
  • CSS擴充套件: text

    • :text("substring")當元素的文字在某處包含"substring"時進行匹配。匹配是不區分大小寫的。匹配還對空格進行規範化,例如,它將多個空格轉換為一個空格,換行並忽略開頭和結尾的空格
    • :text-is("string")當元素的文字等於"string"時進行匹配。匹配不區分大小寫,並且對空格規格化
    • button:text("Sign in")文字選擇器可以與常規CSS相結合
    • :text-matches("[+-]?\\d+")根據正則表示式匹配文字。注意,像反斜槓\,引號",方括號[]和更多的特殊字元應該被轉義。
    • :text-matches("value", "i")使用指定的標記匹配正則表示式的文字
    page.click('button:text("Sign in")')
    page.querySelector(':text("163網易郵箱")').textContent()
    

參考