playwright-python 元素定位、frame處理
阿新 • • 發佈:2020-12-30
瀏覽器、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有三種方法:
frame
的name
屬性frame
的URL
- 通過其他的任何的
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
,甚至文字內容
)來搜尋元素。只需直接使用即可,可以自動探測
簡寫
- 選擇器以
//
或者..
開頭,則會預設為是xpath=selector
- 例子:
page.click('//html')
可轉換為page.click('xpath=//html')
- 例子:
- 選擇器開始和結束以引號(
"
或者'
),則預設為text=selector
- 例子:
page.click(' "foo" ')
可轉換為page.click('text="foo"')
- 例子:
- 其他的預設為是
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()