playwright學(xué)習(xí)筆記
playwright api地址
https://playwright.dev/dotnet/docs/writing-tests
https://mp.weixin.qq.com/s?__biz=MzkxMDM1NDQ0OA==&mid=2247498458&idx=2&sn=a93d4ce571ca5d70a779aae9b596f4ae&source=41#wechat_redirect
https://blog.csdn.net/karl41/article/details/119334673
https://article.itxueyuan.com/ZoLrDw
https://betheme.net/dashuju/96613.html?action=onClick
Python開(kāi)源自動(dòng)化工具Playwright安裝及介紹使用
它支持主流的瀏覽器,包含:Chrome、Firefox、Safari、Microsoft Edge 等,同時(shí)支持以無(wú)頭模式、有頭模式運(yùn)行,并提供了同步、異步的 API,可以結(jié)合 Pytest 測(cè)試框架 使用,并且支持瀏覽器端的自動(dòng)化腳本錄制。
項(xiàng)目地址:https://github.com/microsoft/playwright-python
官網(wǎng):https://playwright.dev/
2、Playwright安裝
Playwright功能強(qiáng)大,但它的安裝步驟,非常簡(jiǎn)單,只需要 2 步:
第 1 步,安裝 playwright-python 依賴(lài)庫(kù) (需要注意的是,playwright庫(kù)需要依賴(lài)Python3.7+以上)
#此處可能是pip/pip3,或者兩者皆可
pip3 install playwright
可以在https://pypi.org/project/playwright/查看它的依賴(lài)版本信息。
第 2 步,安裝主流的瀏覽器驅(qū)動(dòng)
這樣,會(huì)將 Chromeium、Firefox、Webkit 瀏覽器驅(qū)動(dòng)下載到本地
#安裝瀏覽器驅(qū)動(dòng)(安裝過(guò)程稍微有點(diǎn)慢,請(qǐng)耐心等待)
python3 -m playwright install
如果想查看Playwright支持的功能, 可以直接在命令行輸入:
python3 -m playwright help
1)錄制腳本
python3 -m playwright codegen --help
python3 -m playwright codegen --target python -o 'mikezhou.py' -b chromium https://www.baidu.com
命令行輸入后會(huì)自動(dòng)打開(kāi)瀏覽器,然后可以看見(jiàn)在瀏覽器上的一舉一動(dòng)都會(huì)被自動(dòng)翻譯成代碼,如下所示:
最后,自動(dòng)化腳本會(huì)自動(dòng)生成,保存到文件中mikezhou.py, 且上述所有的人工操作,都會(huì)被自動(dòng)轉(zhuǎn)化成代碼:
1.cookies
設(shè)計(jì)思路
對(duì)于一些登錄比較復(fù)雜的網(wǎng)站,具有反爬蟲(chóng)機(jī)制,比如手機(jī)驗(yàn)證碼、滑塊驗(yàn)證等,這時(shí)可以通過(guò)人工手動(dòng)登錄后,保存cookies到指定文件,以后登錄就可以通過(guò)加載已保存的cookies實(shí)現(xiàn)免登陸啦。
1、打開(kāi)網(wǎng)站登錄頁(yè)面;
2、設(shè)置等待時(shí)間,進(jìn)行手工登錄;
3、登錄后獲取并保存cookies。
from playwright.sync_api import sync_playwright
import json
# 先手動(dòng)登錄,保存Cooies到文件。
def saveCookies():
with sync_playwright() as p:
# 顯示瀏覽器,每步操作等待100毫秒
browser = p.firefox.launch(headless=False, slow_mo=100)
context = browser.new_context()
# context.add_init_script(js)
page = context.new_page()
page.goto('https://cq.meituan.com/', timeout=50000) # 設(shè)置超時(shí)時(shí)間為50s
time.sleep(80) # 此處手動(dòng)登錄,然后到個(gè)人信息頁(yè)再獲取cookie
cookies = context.cookies()
print(page.title())
browser.close()
f = open('cookies.txt', 'w')
json.dump(cookies, f)
print('已獲取cookies')
time.sleep(2)
browser.close()
saveCookies()#執(zhí)行函數(shù)
playwright手動(dòng)設(shè)置cookies和獲取cookies的方法
const browser = await chromium.launch({
headless: false
});
const context = await browser.newContext();
const page = await context.newPage();
context.addCookies([
{
"name": ".AspNetCore.Antiforgery.v2CUd5wyqKo",
"domain": "xxxx.com",
"value": "CfDJ8LY97Wcbz7VCv7_x1JiYm96-2kqovbTwK88qSQBNMPKiYPcwfz9WwDsAT72aQUEaQETi3UFYMh9_Kob9nffYFT0A8QqIe7AB96hrgiW0zntQqwBOJASYccsK8ubkZxa2ZN5darwFzORs5ws7s-8BcHA"
"path": "/"
}
])
await page.goto('https://xxxx.com/');
Playwright選擇器
CSS選擇器
標(biāo)簽
html元素標(biāo)簽,直接寫(xiě)標(biāo)簽名,如
<button value="title"></button> 1
page.click('button') # 點(diǎn)擊標(biāo)簽為button的按鈕
page.locator("button").click()
ID
元素中的ID屬性,在ID前標(biāo)識(shí)#,如
<input id="user"></input>
page.fill('#user', 'username') # 在id=user的輸入框中輸入username
page.locator('#main-nav-menu [href="/topics"]').click()
Class
元素中的class屬性,在class前標(biāo)識(shí).,如
<input class="btn" type="button"></input>
1
page.click('.btn') # 點(diǎn)擊class為btn的按鈕
其他屬性
元素中除ID和Class的其他屬性,使用[attr<=value>]語(yǔ)法,如
<input type="password"></input>
<input type="checkbox" name="vehicle" value="Bike" checked>I have a bike<br>
page.fill('[type=password]', 'password') # 在具有屬性type=password的輸入框中輸入password
page.click('[checked]') # 點(diǎn)擊具有屬性checked的按鈕
page.locator('[href="/topics"]').click()
多種屬性同時(shí)使用
上述多種選擇器可以同時(shí)使用,連在一起寫(xiě)即可,如
page.fill('input[type=password]', 'password') # 在具有屬性type=password同時(shí)標(biāo)簽為input的輸入框中輸入passwordpage.click('input.btn') # 點(diǎn)擊class為btn同時(shí)標(biāo)簽為input的按鈕
組合選擇器
當(dāng)元素本身的屬性不足以唯一定位到我們想要的元素時(shí),可以使用組合選擇器,通過(guò)元素的父節(jié)點(diǎn)或祖先節(jié)點(diǎn)來(lái)進(jìn)行唯一定位,如
<div id="user"><button></button></div><div id="userinfo"><button></button></div>
page.click('#userinfo button') # 點(diǎn)擊id為userinfo內(nèi)部的標(biāo)簽為button的按鈕,使用空格分隔page.click('#userinfo>button') # 點(diǎn)擊父元素為id為userinfo的標(biāo)簽為button的按鈕,使用>分隔
偽類(lèi)
并非頁(yè)面上的屬性,而是某種表現(xiàn)形式,可以理解為函數(shù),通過(guò):進(jìn)行調(diào)用,如
page.click('input:nth-child(2)') # 點(diǎn)擊具有同一個(gè)父節(jié)點(diǎn)的第二個(gè)inputpage.click('button:not([disabled])') # 點(diǎn)擊不具有disabled屬性的button按鈕
XPATH選擇器
由于playwright自定義的擴(kuò)展選擇器使用的是CSS選擇器語(yǔ)法,所以建議在使用playwright時(shí)主要使用CSS選擇器,將XPATH選擇器作為補(bǔ)充使用。
Xpath與Iframes互動(dòng)
iframe1 = page.query_selector('xpath=//iframe[@title="payment"]').content_frame()
time.sleep(5)
iframe1.fill('//*[@id="cardCvc-input"]', '123')
page.navigate("https://antdv.com/components/modal-cn");
page.querySelector("#components-modal-demo-basic .code-box-demo span").click();
page.locator("http://div[@id='vcDialogTitle0']|//div[@role='documentcontent']").waitFor();
System.out.println();
文本選擇器
文本選擇器按照頁(yè)面顯示出的文本定位元素
page.click("text=Log in") # 點(diǎn)擊包含文字Log in的元素,不區(qū)分大小寫(xiě)且匹配子字符串page.click("text='Log in'") # 文字通過(guò)使用引號(hào)進(jìn)行轉(zhuǎn)義,表示只搜索準(zhǔn)確文本節(jié)點(diǎn)Log in的元素page.click("'Log in'") # 等同于text='Log in'page.click("text=/Log\s*in/i") # javascript正則表達(dá)式語(yǔ)法支持page.click("#nav-bar :text('Home')") # text偽類(lèi)等同于text=*,用于配合CSS選擇器一起使用page.click('#nav-bar :text-is("Home")') # text-is偽類(lèi)等同于text='*',嚴(yán)格匹配文字page.click('#nav-bar :text-matches("reg?ex", "i")') # text=matches偽類(lèi)等同于text=/reg?ex/i,匹配正則表達(dá)式page.click('article:has-text("All products")') # has-text偽類(lèi)匹配所有包含內(nèi)部文字的元素,包括body,一般需要配合css選擇器一起使用
page.locator("text=社區(qū)").click()
page.locator("#main-nav-menu :text('社區(qū)')").click()
page.locator('article:has-text("All products")').click()
定位可見(jiàn)元素
:visible偽類(lèi)匹配可見(jiàn)的元素。例如,input匹配頁(yè)面上的所有輸入框,而input:visible僅匹配可見(jiàn)輸入框。這對(duì)于區(qū)分非常相似但可見(jiàn)性不同的元素很有用。
例如有兩個(gè)按鈕的頁(yè)面,第一個(gè)是不可見(jiàn)的,第二個(gè)是可見(jiàn)的:
<button style='display: none'>Invisible</button><button>Visible</button>
page.click("button") # 定位到第一個(gè)按鈕,因?yàn)樗堑谝粋€(gè)。然后等待按鈕變?yōu)榭梢?jiàn)后點(diǎn)擊,或超時(shí)page.click("button:visible") # 定位到第二個(gè)按鈕,因?yàn)樗强梢?jiàn)的
:visible需要小心使用,它有兩個(gè)主要缺點(diǎn):
當(dāng)元素動(dòng)態(tài)更改其可見(jiàn)性時(shí),:visible將基于時(shí)序給出不可預(yù)測(cè)的結(jié)果。
:visible可能導(dǎo)致查詢(xún)變慢,尤其是與方法page.waitForSelector(selector[, options])一起使用時(shí)
page.locator("button:visible").click()
page.locator("button >> visible=true").click()
按包含的元素定位
:has 偽類(lèi)是實(shí)驗(yàn)性的,它將定位到包含所給元素定位的元素,如下代碼返回包含 <div class="promo">元素的 <article>的元素的文本內(nèi)容:
page.textContent("article:has(div.promo)")
playwright可以根據(jù)頁(yè)面布局選擇元素,與常規(guī)CSS結(jié)合使用以獲得更好的效果,例如 input:right-of(:text("Password"))匹配文本"Password"右側(cè)的輸入框
:right-of(inner > selector)- 匹配與內(nèi)部選擇器匹配的任何元素右側(cè)的元素。
:left-of(inner > selector)- 匹配與內(nèi)部選擇器匹配的任何元素左側(cè)的元素。
:above(inner > selector)- 匹配位于與內(nèi)部選擇器匹配的任何元素上方的元素。
:below(inner > selector)- 匹配與內(nèi)部選擇器匹配的任何元素下方的元素。
:near(inner > selector)- 匹配與內(nèi)部選擇器匹配的任何元素附近(50 個(gè) CSS 像素內(nèi))的元素
# 在"Username"右側(cè)的輸入框中填寫(xiě)'value'.page.fill('input:right-of(:text("Username"))', 'value')# 點(diǎn)擊 promo card 附近的按鈕.page.click('button:near(.promo-card)')
page.locator("input:right-of(:text('開(kāi)源項(xiàng)目'))").fill('電子校的故事')
定位第n個(gè)元素
有時(shí)頁(yè)面包含許多相似的元素,并且很難選擇特定的元素。例如:
<section> <button>Buy</button> </section><article><div> <button>Buy</button> </div></article><div><div> <button>Buy</button> </div></div>
在這種情況下, :nth-match(:text("Buy"), 3)將從上面的片段中選擇第三個(gè)按鈕。請(qǐng)注意,索引是從 1 開(kāi)始的。
可以使用:nth-match()配合 page.wait_for_selector(selector, **kwargs)等待指定數(shù)量的元素出現(xiàn):
# 等到出現(xiàn)3個(gè)可見(jiàn)的按鈕page.wait_for_selector(":nth-match(:text('Buy'), 3)")
注意:不同于 :nth-child(),元素不一定是兄弟元素,可以是位于頁(yè)面上的任何位置
常用
1.text selecter
# Find by text.
page.locator("text=Sign up").click()
2.Css selecter
# Find by CSS.
page.locator("#nav-bar .contact-us-item").click()
3.css and text selecter
page.locator("article:has-text('Playwright')").click()
page.locator("#nav-bar :text('Contact us')").click()
4.css and another selecter
page.locator(".item-description:has(.item-promo-banner)").click()
5.layout selecter
# Fill an input to the right of "Username".
page.locator("input:right-of(:text(\"Username\"))").fill("value")
# Click a button near the promo card.
page.locator("button:near(.promo-card)").click()
# Click the radio input in the list closest to the "Label 3".
page.locator("[type=radio]:left-of(:text(\"Label 3\"))").first.click()
2.Filtering Locators
page.locator("button", has_text="Sign up").click()
page.locator("article", has=page.locator("button.subscribe"))
3.pick n-th application
For Example:
<section> <button>Buy</button> </section>
<article><div> <button>Buy</button> </div></article>
<div><div> <button>Buy</button> </div></div>
# Click the third "Buy" button
page.locator(":nth-match(:text('Buy'), 3)").click()
# Wait until all three buttons are visible
page.locator(":nth-match(:text('Buy'), 3)").wait_for()
import asyncio
from playwright.async_api import async_playwrightasync def main():with async_playwright() as p:browser = p.chromium.launch()# 創(chuàng)建新的隱身瀏覽器上下文context = await browser.new_context()# 在上下文中創(chuàng)建新頁(yè)面。page = await context.new_page()await page.goto("https://www.baidu.com")await context.close()
三、頁(yè)面和框架
瀏覽器上下文可以有多個(gè)頁(yè)面。頁(yè)面是指瀏覽器上下文中的單個(gè)選項(xiàng)卡或彈出窗口
四、Selectors
Playwright可以使用CSS選擇器,XPath選擇器,HTML屬性(如)test、id、data-test-id等屬性來(lái)定位元素。
1、data-test-id= selector
#同步
page.click('data-test-id=foo')
#異步步
await page.click('data-test-id=foo')
2、CSS and XPath selector
#同步
page.click('div')
page.click('//html/body/div')
#異步
await page.click('div')
await page.click('//html/body/div')
3、text 文本selector
page.click('text=Hello')
4、id定位selector
page.fill("id=kw", "csdn")
5、Selector 組合定位
不同的selector可組合使用,用 >>連接。
#單擊#free month promo中帶有文本“Sign Up”的元素
page.click('#free-month-promo >> text=Sign Up')
五、內(nèi)置Selector
playwright 推薦的內(nèi)置定位器:
1. page.get_by_text()通過(guò)文本內(nèi)容定位
2. page.get_by_label()通過(guò)關(guān)聯(lián)標(biāo)簽的文本定位表單控件
3. page.get_by_placeholder()按占位符定位輸入
4. page.get_by_test_id()根據(jù)data-testid屬性定位元素(可以配置其他屬性)
5. page.get_by_role()通過(guò)顯式和隱式可訪(fǎng)問(wèn)性屬性進(jìn)行定位
6. page.get_by_alt_text()通過(guò)替代文本定位元素,通常是圖像
7. page.get_by_title()通過(guò)標(biāo)題屬性定位元素
https://playwright.dev/dotnet/docs/writing-tests
https://mp.weixin.qq.com/s?__biz=MzkxMDM1NDQ0OA==&mid=2247498458&idx=2&sn=a93d4ce571ca5d70a779aae9b596f4ae&source=41#wechat_redirect
https://blog.csdn.net/karl41/article/details/119334673
https://article.itxueyuan.com/ZoLrDw
https://betheme.net/dashuju/96613.html?action=onClick
Python開(kāi)源自動(dòng)化工具Playwright安裝及介紹使用
它支持主流的瀏覽器,包含:Chrome、Firefox、Safari、Microsoft Edge 等,同時(shí)支持以無(wú)頭模式、有頭模式運(yùn)行,并提供了同步、異步的 API,可以結(jié)合 Pytest 測(cè)試框架 使用,并且支持瀏覽器端的自動(dòng)化腳本錄制。
項(xiàng)目地址:https://github.com/microsoft/playwright-python
官網(wǎng):https://playwright.dev/
2、Playwright安裝
Playwright功能強(qiáng)大,但它的安裝步驟,非常簡(jiǎn)單,只需要 2 步:
第 1 步,安裝 playwright-python 依賴(lài)庫(kù) (需要注意的是,playwright庫(kù)需要依賴(lài)Python3.7+以上)
#此處可能是pip/pip3,或者兩者皆可
pip3 install playwright
可以在https://pypi.org/project/playwright/查看它的依賴(lài)版本信息。
第 2 步,安裝主流的瀏覽器驅(qū)動(dòng)
這樣,會(huì)將 Chromeium、Firefox、Webkit 瀏覽器驅(qū)動(dòng)下載到本地
#安裝瀏覽器驅(qū)動(dòng)(安裝過(guò)程稍微有點(diǎn)慢,請(qǐng)耐心等待)
python3 -m playwright install
如果想查看Playwright支持的功能, 可以直接在命令行輸入:
python3 -m playwright help
1)錄制腳本
python3 -m playwright codegen --help
python3 -m playwright codegen --target python -o 'mikezhou.py' -b chromium https://www.baidu.com
命令行輸入后會(huì)自動(dòng)打開(kāi)瀏覽器,然后可以看見(jiàn)在瀏覽器上的一舉一動(dòng)都會(huì)被自動(dòng)翻譯成代碼,如下所示:
最后,自動(dòng)化腳本會(huì)自動(dòng)生成,保存到文件中mikezhou.py, 且上述所有的人工操作,都會(huì)被自動(dòng)轉(zhuǎn)化成代碼:
1.cookies
設(shè)計(jì)思路
對(duì)于一些登錄比較復(fù)雜的網(wǎng)站,具有反爬蟲(chóng)機(jī)制,比如手機(jī)驗(yàn)證碼、滑塊驗(yàn)證等,這時(shí)可以通過(guò)人工手動(dòng)登錄后,保存cookies到指定文件,以后登錄就可以通過(guò)加載已保存的cookies實(shí)現(xiàn)免登陸啦。
1、打開(kāi)網(wǎng)站登錄頁(yè)面;
2、設(shè)置等待時(shí)間,進(jìn)行手工登錄;
3、登錄后獲取并保存cookies。
from playwright.sync_api import sync_playwright
import json
# 先手動(dòng)登錄,保存Cooies到文件。
def saveCookies():
with sync_playwright() as p:
# 顯示瀏覽器,每步操作等待100毫秒
browser = p.firefox.launch(headless=False, slow_mo=100)
context = browser.new_context()
# context.add_init_script(js)
page = context.new_page()
page.goto('https://cq.meituan.com/', timeout=50000) # 設(shè)置超時(shí)時(shí)間為50s
time.sleep(80) # 此處手動(dòng)登錄,然后到個(gè)人信息頁(yè)再獲取cookie
cookies = context.cookies()
print(page.title())
browser.close()
f = open('cookies.txt', 'w')
json.dump(cookies, f)
print('已獲取cookies')
time.sleep(2)
browser.close()
saveCookies()#執(zhí)行函數(shù)
playwright手動(dòng)設(shè)置cookies和獲取cookies的方法
const browser = await chromium.launch({
headless: false
});
const context = await browser.newContext();
const page = await context.newPage();
context.addCookies([
{
"name": ".AspNetCore.Antiforgery.v2CUd5wyqKo",
"domain": "xxxx.com",
"value": "CfDJ8LY97Wcbz7VCv7_x1JiYm96-2kqovbTwK88qSQBNMPKiYPcwfz9WwDsAT72aQUEaQETi3UFYMh9_Kob9nffYFT0A8QqIe7AB96hrgiW0zntQqwBOJASYccsK8ubkZxa2ZN5darwFzORs5ws7s-8BcHA"
"path": "/"
}
])
await page.goto('https://xxxx.com/');
Playwright選擇器
CSS選擇器
標(biāo)簽
html元素標(biāo)簽,直接寫(xiě)標(biāo)簽名,如
<button value="title"></button> 1
page.click('button') # 點(diǎn)擊標(biāo)簽為button的按鈕
page.locator("button").click()
ID
元素中的ID屬性,在ID前標(biāo)識(shí)#,如
<input id="user"></input>
page.fill('#user', 'username') # 在id=user的輸入框中輸入username
page.locator('#main-nav-menu [href="/topics"]').click()
Class
元素中的class屬性,在class前標(biāo)識(shí).,如
<input class="btn" type="button"></input>
1
page.click('.btn') # 點(diǎn)擊class為btn的按鈕
其他屬性
元素中除ID和Class的其他屬性,使用[attr<=value>]語(yǔ)法,如
<input type="password"></input>
<input type="checkbox" name="vehicle" value="Bike" checked>I have a bike<br>
page.fill('[type=password]', 'password') # 在具有屬性type=password的輸入框中輸入password
page.click('[checked]') # 點(diǎn)擊具有屬性checked的按鈕
page.locator('[href="/topics"]').click()
多種屬性同時(shí)使用
上述多種選擇器可以同時(shí)使用,連在一起寫(xiě)即可,如
page.fill('input[type=password]', 'password') # 在具有屬性type=password同時(shí)標(biāo)簽為input的輸入框中輸入passwordpage.click('input.btn') # 點(diǎn)擊class為btn同時(shí)標(biāo)簽為input的按鈕
組合選擇器
當(dāng)元素本身的屬性不足以唯一定位到我們想要的元素時(shí),可以使用組合選擇器,通過(guò)元素的父節(jié)點(diǎn)或祖先節(jié)點(diǎn)來(lái)進(jìn)行唯一定位,如
<div id="user"><button></button></div><div id="userinfo"><button></button></div>
page.click('#userinfo button') # 點(diǎn)擊id為userinfo內(nèi)部的標(biāo)簽為button的按鈕,使用空格分隔page.click('#userinfo>button') # 點(diǎn)擊父元素為id為userinfo的標(biāo)簽為button的按鈕,使用>分隔
偽類(lèi)
并非頁(yè)面上的屬性,而是某種表現(xiàn)形式,可以理解為函數(shù),通過(guò):進(jìn)行調(diào)用,如
page.click('input:nth-child(2)') # 點(diǎn)擊具有同一個(gè)父節(jié)點(diǎn)的第二個(gè)inputpage.click('button:not([disabled])') # 點(diǎn)擊不具有disabled屬性的button按鈕
XPATH選擇器
由于playwright自定義的擴(kuò)展選擇器使用的是CSS選擇器語(yǔ)法,所以建議在使用playwright時(shí)主要使用CSS選擇器,將XPATH選擇器作為補(bǔ)充使用。
Xpath與Iframes互動(dòng)
iframe1 = page.query_selector('xpath=//iframe[@title="payment"]').content_frame()
time.sleep(5)
iframe1.fill('//*[@id="cardCvc-input"]', '123')
page.navigate("https://antdv.com/components/modal-cn");
page.querySelector("#components-modal-demo-basic .code-box-demo span").click();
page.locator("http://div[@id='vcDialogTitle0']|//div[@role='documentcontent']").waitFor();
System.out.println();
文本選擇器
文本選擇器按照頁(yè)面顯示出的文本定位元素
page.click("text=Log in") # 點(diǎn)擊包含文字Log in的元素,不區(qū)分大小寫(xiě)且匹配子字符串page.click("text='Log in'") # 文字通過(guò)使用引號(hào)進(jìn)行轉(zhuǎn)義,表示只搜索準(zhǔn)確文本節(jié)點(diǎn)Log in的元素page.click("'Log in'") # 等同于text='Log in'page.click("text=/Log\s*in/i") # javascript正則表達(dá)式語(yǔ)法支持page.click("#nav-bar :text('Home')") # text偽類(lèi)等同于text=*,用于配合CSS選擇器一起使用page.click('#nav-bar :text-is("Home")') # text-is偽類(lèi)等同于text='*',嚴(yán)格匹配文字page.click('#nav-bar :text-matches("reg?ex", "i")') # text=matches偽類(lèi)等同于text=/reg?ex/i,匹配正則表達(dá)式page.click('article:has-text("All products")') # has-text偽類(lèi)匹配所有包含內(nèi)部文字的元素,包括body,一般需要配合css選擇器一起使用
page.locator("text=社區(qū)").click()
page.locator("#main-nav-menu :text('社區(qū)')").click()
page.locator('article:has-text("All products")').click()
定位可見(jiàn)元素
:visible偽類(lèi)匹配可見(jiàn)的元素。例如,input匹配頁(yè)面上的所有輸入框,而input:visible僅匹配可見(jiàn)輸入框。這對(duì)于區(qū)分非常相似但可見(jiàn)性不同的元素很有用。
例如有兩個(gè)按鈕的頁(yè)面,第一個(gè)是不可見(jiàn)的,第二個(gè)是可見(jiàn)的:
<button style='display: none'>Invisible</button><button>Visible</button>
page.click("button") # 定位到第一個(gè)按鈕,因?yàn)樗堑谝粋€(gè)。然后等待按鈕變?yōu)榭梢?jiàn)后點(diǎn)擊,或超時(shí)page.click("button:visible") # 定位到第二個(gè)按鈕,因?yàn)樗强梢?jiàn)的
:visible需要小心使用,它有兩個(gè)主要缺點(diǎn):
當(dāng)元素動(dòng)態(tài)更改其可見(jiàn)性時(shí),:visible將基于時(shí)序給出不可預(yù)測(cè)的結(jié)果。
:visible可能導(dǎo)致查詢(xún)變慢,尤其是與方法page.waitForSelector(selector[, options])一起使用時(shí)
page.locator("button:visible").click()
page.locator("button >> visible=true").click()
按包含的元素定位
:has 偽類(lèi)是實(shí)驗(yàn)性的,它將定位到包含所給元素定位的元素,如下代碼返回包含 <div class="promo">元素的 <article>的元素的文本內(nèi)容:
page.textContent("article:has(div.promo)")
playwright可以根據(jù)頁(yè)面布局選擇元素,與常規(guī)CSS結(jié)合使用以獲得更好的效果,例如 input:right-of(:text("Password"))匹配文本"Password"右側(cè)的輸入框
:right-of(inner > selector)- 匹配與內(nèi)部選擇器匹配的任何元素右側(cè)的元素。
:left-of(inner > selector)- 匹配與內(nèi)部選擇器匹配的任何元素左側(cè)的元素。
:above(inner > selector)- 匹配位于與內(nèi)部選擇器匹配的任何元素上方的元素。
:below(inner > selector)- 匹配與內(nèi)部選擇器匹配的任何元素下方的元素。
:near(inner > selector)- 匹配與內(nèi)部選擇器匹配的任何元素附近(50 個(gè) CSS 像素內(nèi))的元素
# 在"Username"右側(cè)的輸入框中填寫(xiě)'value'.page.fill('input:right-of(:text("Username"))', 'value')# 點(diǎn)擊 promo card 附近的按鈕.page.click('button:near(.promo-card)')
page.locator("input:right-of(:text('開(kāi)源項(xiàng)目'))").fill('電子校的故事')
定位第n個(gè)元素
有時(shí)頁(yè)面包含許多相似的元素,并且很難選擇特定的元素。例如:
<section> <button>Buy</button> </section><article><div> <button>Buy</button> </div></article><div><div> <button>Buy</button> </div></div>
在這種情況下, :nth-match(:text("Buy"), 3)將從上面的片段中選擇第三個(gè)按鈕。請(qǐng)注意,索引是從 1 開(kāi)始的。
可以使用:nth-match()配合 page.wait_for_selector(selector, **kwargs)等待指定數(shù)量的元素出現(xiàn):
# 等到出現(xiàn)3個(gè)可見(jiàn)的按鈕page.wait_for_selector(":nth-match(:text('Buy'), 3)")
注意:不同于 :nth-child(),元素不一定是兄弟元素,可以是位于頁(yè)面上的任何位置
常用
1.text selecter
# Find by text.
page.locator("text=Sign up").click()
2.Css selecter
# Find by CSS.
page.locator("#nav-bar .contact-us-item").click()
3.css and text selecter
page.locator("article:has-text('Playwright')").click()
page.locator("#nav-bar :text('Contact us')").click()
4.css and another selecter
page.locator(".item-description:has(.item-promo-banner)").click()
5.layout selecter
# Fill an input to the right of "Username".
page.locator("input:right-of(:text(\"Username\"))").fill("value")
# Click a button near the promo card.
page.locator("button:near(.promo-card)").click()
# Click the radio input in the list closest to the "Label 3".
page.locator("[type=radio]:left-of(:text(\"Label 3\"))").first.click()
2.Filtering Locators
page.locator("button", has_text="Sign up").click()
page.locator("article", has=page.locator("button.subscribe"))
3.pick n-th application
For Example:
<section> <button>Buy</button> </section>
<article><div> <button>Buy</button> </div></article>
<div><div> <button>Buy</button> </div></div>
# Click the third "Buy" button
page.locator(":nth-match(:text('Buy'), 3)").click()
# Wait until all three buttons are visible
page.locator(":nth-match(:text('Buy'), 3)").wait_for()
import asyncio
from playwright.async_api import async_playwrightasync def main():with async_playwright() as p:browser = p.chromium.launch()# 創(chuàng)建新的隱身瀏覽器上下文context = await browser.new_context()# 在上下文中創(chuàng)建新頁(yè)面。page = await context.new_page()await page.goto("https://www.baidu.com")await context.close()
三、頁(yè)面和框架
瀏覽器上下文可以有多個(gè)頁(yè)面。頁(yè)面是指瀏覽器上下文中的單個(gè)選項(xiàng)卡或彈出窗口
四、Selectors
Playwright可以使用CSS選擇器,XPath選擇器,HTML屬性(如)test、id、data-test-id等屬性來(lái)定位元素。
1、data-test-id= selector
#同步
page.click('data-test-id=foo')
#異步步
await page.click('data-test-id=foo')
2、CSS and XPath selector
#同步
page.click('div')
page.click('//html/body/div')
#異步
await page.click('div')
await page.click('//html/body/div')
3、text 文本selector
page.click('text=Hello')
4、id定位selector
page.fill("id=kw", "csdn")
5、Selector 組合定位
不同的selector可組合使用,用 >>連接。
#單擊#free month promo中帶有文本“Sign Up”的元素
page.click('#free-month-promo >> text=Sign Up')
五、內(nèi)置Selector
playwright 推薦的內(nèi)置定位器:
1. page.get_by_text()通過(guò)文本內(nèi)容定位
2. page.get_by_label()通過(guò)關(guān)聯(lián)標(biāo)簽的文本定位表單控件
3. page.get_by_placeholder()按占位符定位輸入
4. page.get_by_test_id()根據(jù)data-testid屬性定位元素(可以配置其他屬性)
5. page.get_by_role()通過(guò)顯式和隱式可訪(fǎng)問(wèn)性屬性進(jìn)行定位
6. page.get_by_alt_text()通過(guò)替代文本定位元素,通常是圖像
7. page.get_by_title()通過(guò)標(biāo)題屬性定位元素

浙公網(wǎng)安備 33010602011771號(hào)