Playwright,微軟瀏覽器自動(dòng)化教程(二)

Playwright,微軟瀏覽器自動(dòng)化教程(二)
核心概念同窘,建議結(jié)合第一節(jié)的內(nèi)容具體理解

1、Browser

這是一個(gè)瀏覽器實(shí)例部脚,腳本運(yùn)行需要首先打開(kāi)瀏覽器實(shí)例

# playwright.brwoser_type.action(**kwargs)可以理解為指定瀏覽器內(nèi)核
browser = playwright.chromium.launch(channel="chrome",headless=False)
# launch是最常用的一個(gè)函數(shù)想邦,他有大量的參數(shù),這里介紹常用的的
headless    是否顯示GUI,默認(rèn)是TRUE不顯示
channel     指定瀏覽器版本委刘,"chrome", "chrome-beta", "chrome-dev", "chrome-canary",
proxy       瀏覽器代理設(shè)置
timeout     等待超時(shí)時(shí)間丧没,默認(rèn)30000ms(30s)
slow_mo     減慢操作速度,浮點(diǎn)型锡移,一邊可以看清楚操作

順便說(shuō)一下呕童,playwright的所有操作都有自動(dòng)等待的功能,時(shí)間都是30s

2淆珊、Browser contexts

這個(gè)是獨(dú)立的瀏覽器夺饲,隱身對(duì)話,意思是每一個(gè)Beowser contexts都是獨(dú)立的,互相之間沒(méi)有關(guān)系往声,等于說(shuō)全都是新裝的瀏覽器擂找。

# 根據(jù)瀏覽器內(nèi)核創(chuàng)建瀏覽器
context = browser.new_context(accept_downloads=False)
# 創(chuàng)建新頁(yè)面
page = context.new_page()

2.1、browser.new_context

# browser.new_context的參數(shù)包括所有跟瀏覽器設(shè)置相關(guān)的
# 可以理解為根據(jù)瀏覽器創(chuàng)建一個(gè)新的瀏覽器
accept_downloads      是否下載所有附件浩销,默認(rèn)False不下載
geolocation           設(shè)定經(jīng)緯度
user_agent            設(shè)定user agent
viewport              設(shè)定頁(yè)面大小贯涎,規(guī)格,例如1280*720
offline               離線模式加載

2.2慢洋、context

# context就是瀏覽器層面的操作
context.new_page()      返回一個(gè)新頁(yè)面
context.pages           返回所有打開(kāi)的頁(yè)面[list]
context.add_cookies([cookie_object1, cookie_object2])   添加cookie
context.cookies()       返回cookie
context.wait_for_event(event, **kwargs) 等待event完成

3塘雳、Pages and frames

一個(gè) Browser contexts 有多個(gè)pages,一個(gè) page 是一個(gè)單獨(dú)的tab普筹,或者彈出窗口败明。用于導(dǎo)航到url ,或者與頁(yè)面交互斑芜,比如點(diǎn)擊肩刃,輸入文字等。
一個(gè) page 有多個(gè) Frame (框架)杏头,框架內(nèi)的操作無(wú)法通過(guò)page.**操作盈包,只能通過(guò)page.Frame.func()操作,但是通常在錄制模式下醇王,他會(huì)自動(dòng)識(shí)別是否是框架內(nèi)的操作呢燥,如果不懂怎么定位框架,那么可以使用錄制模式來(lái)找寓娩。


3.1叛氨、Pages

大部分操作都是在page層面的,所以page有最多的函數(shù)

from playwright.sync_api import sync_playwright
# 這是一個(gè)創(chuàng)建頁(yè)面棘伴,定位到指定鏈接寞埠,并截屏保存的例子
def run(playwright):
    webkit = playwright.webkit
    browser = webkit.launch()
    context = browser.new_context()
    page = context.new_page()
    page.goto("https://example.com")
    page.screenshot(path="screenshot.png")
    browser.close()

with sync_playwright() as playwright:
    run(playwright)

常用的函數(shù)有,一般看名字就知道是干嘛的

page.click(selector, **kwargs)
page.content()      # 獲取頁(yè)面的html
page.screenshot(**kwargs)
page.goto(url, **kwargs)
page.pdf(**kwargs)
page.reload(**kwargs)
page.wait_for_timeout(timeout)
page.get_attribute(selector, name, **kwargs)

# page的expect_**函數(shù)需要注意
# 這個(gè)類型的函數(shù)一般都伴隨這with使用
# 下面這個(gè)例子就是點(diǎn)擊按鈕后焊夸,改變了頁(yè)面框架
with page.expect_event("framenavigated") as event_info:
    page.click("button")
frame = event_info.value
#這樣的還有很多仁连,比如,大都用在交互的對(duì)象改變的情況下
page.expect_file_chooser(**kwargs)
page.expect_navigation(**kwargs)
page.expect_popup(**kwargs)

# 個(gè)人推薦注意這幾個(gè)is的方法阱穗,在等待頁(yè)面的時(shí)候很有用
page.is_disabled/(selector, **kwargs)
is_editable饭冬,is_enabled,is_hidden揪阶,is_visible

# 還有一個(gè)特殊的方法
page.locator(selector)      # 定位頁(yè)面元素昌抠,返回的是locator對(duì)象

3.2、Frame

frame的操作大部分跟page一樣鲁僚,只不過(guò)framepage下一級(jí)的炊苫,可以理解為在page里嵌套的一個(gè)小頁(yè)面裁厅。但是還是有一點(diǎn)不一樣。
page里分為主框架和子框架劝评,這里有一個(gè)框架樹(shù)的例子,大家可以運(yùn)行下試試姐直。

from playwright.sync_api import sync_playwright

def run(playwright):
    firefox = playwright.firefox
    browser = firefox.launch()
    page = browser.new_page()
    page.goto("https://www.theverge.com")
    dump_frame_tree(page.main_frame, "")
    browser.close()

def dump_frame_tree(frame, indent):
    print(indent + frame.name + '@' + frame.url)
    for child in frame.child_frames:
        dump_frame_tree(child, indent + "    ")

with sync_playwright() as playwright:
    run(playwright)

其方法大部分都與page一樣,不在贅述蒋畜,注意的是
page.frame(**kwargs)声畏,這個(gè)可以用來(lái)選擇Frame,并返回Frame對(duì)象姻成,所以對(duì)Frame的操作有一下兩種方法插龄。

# 直接定位Frame操作
page.frame(name="frame-name").click('text=hello')

#返回Frame對(duì)象操作
frame = page.frame(name="frame-name")
frame.click('text=hello')

4、Selectors

Playwright可以通過(guò)css,XPath,HTML等選擇元素科展,像id,data-test-id均牢,或者像上面演示的,通過(guò)text內(nèi)容才睹。
這里有一些例子

# Using data-test-id= selector engine
page.click('data-test-id=foo')

# CSS and XPath selector engines are automatically detected
page.click('div')
page.click('//html/body/div')

# Find node by text substring
page.click('text=Hello w')

# 通過(guò) >> 鏈接相同或不同的選擇器
# Click an element with text 'Sign Up' inside of a #free-month-promo.
page.click('#free-month-promo >> text=Sign Up')

我推薦使用瀏覽器的開(kāi)發(fā)者模式來(lái)尋找選擇器:
[圖片上傳失敗...(image-372c61-1649499671696)]

5徘跪、Auto-waiting

所有的操作都會(huì)等待元素可見(jiàn),或者可操作之后才會(huì)進(jìn)行琅攘,也就是自帶等待時(shí)間垮庐,但是如果要自己加等待的話不推薦使用time.sleep(5),而是用page.wait_for_timeout(5000)坞琴。
這里也可以使用page的wait操作:

page.wait_for_event(event, **kwargs)
page.wait_for_function(expression, **kwargs)
page.wait_for_load_state(**kwargs)
page.wait_for_selector(selector, **kwargs)
page.wait_for_timeout(timeout)
page.wait_for_url(url, **kwargs)

6哨查、Evaluation Argument

像 page.evaluate(expression, **kwargs) 這樣的劇作家評(píng)估方法采用單個(gè)可選參數(shù)。 此參數(shù)可以是 Serializable 值和 JSHandle 或 ElementHandle 實(shí)例的混合剧辐。 句柄會(huì)自動(dòng)轉(zhuǎn)換為它們所代表的值寒亥。

# A primitive value.
page.evaluate('num => num', 42)

# An array.
page.evaluate('array => array.length', [1, 2, 3])

# An object.
page.evaluate('object => object.foo', { 'foo': 'bar' })

# A single handle.
button = page.query_selector('button')
page.evaluate('button => button.textContent', button)

# Alternative notation using elementHandle.evaluate.
button.evaluate('(button, from) => button.textContent.substring(from)', 5)

# Object with multiple handles.
button1 = page.query_selector('.button1')
button2 = page.query_selector('.button2')
page.evaluate("""o => o.button1.textContent + o.button2.textContent""",
    { 'button1': button1, 'button2': button2 })

# Object destructuring works. Note that property names must match
# between the destructured object and the argument.
# Also note the required parenthesis.
page.evaluate("""
    ({ button1, button2 }) => button1.textContent + button2.textContent""",
    { 'button1': button1, 'button2': button2 })

# Array works as well. Arbitrary names can be used for destructuring.
# Note the required parenthesis.
page.evaluate("""
    ([b1, b2]) => b1.textContent + b2.textContent""",
    [button1, button2])

# Any non-cyclic mix of serializables and handles works.
page.evaluate("""
    x => x.button1.textContent + x.list[0].textContent + String(x.foo)""",
    { 'button1': button1, 'list': [button2], 'foo': None })

參考文章:
參考鏈接

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市荧关,隨后出現(xiàn)的幾起案子溉奕,更是在濱河造成了極大的恐慌,老刑警劉巖忍啤,帶你破解...
    沈念sama閱讀 217,542評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件加勤,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡檀轨,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門欺嗤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)参萄,“玉大人,你說(shuō)我怎么就攤上這事煎饼《锟妫” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 163,912評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)筒溃。 經(jīng)常有香客問(wèn)我马篮,道長(zhǎng),這世上最難降的妖魔是什么怜奖? 我笑而不...
    開(kāi)封第一講書人閱讀 58,449評(píng)論 1 293
  • 正文 為了忘掉前任浑测,我火速辦了婚禮,結(jié)果婚禮上歪玲,老公的妹妹穿的比我還像新娘迁央。我一直安慰自己,他們只是感情好滥崩,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布岖圈。 她就那樣靜靜地躺著,像睡著了一般钙皮。 火紅的嫁衣襯著肌膚如雪蜂科。 梳的紋絲不亂的頭發(fā)上遭铺,一...
    開(kāi)封第一講書人閱讀 51,370評(píng)論 1 302
  • 那天碳胳,我揣著相機(jī)與錄音拢操,去河邊找鬼优妙。 笑死炎码,一個(gè)胖子當(dāng)著我的面吹牛揭斧,可吹牛的內(nèi)容都是我干的刚夺。 我是一名探鬼主播钥屈,決...
    沈念sama閱讀 40,193評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼屹蚊,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼厕氨!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起汹粤,我...
    開(kāi)封第一講書人閱讀 39,074評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤命斧,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后嘱兼,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體国葬,經(jīng)...
    沈念sama閱讀 45,505評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評(píng)論 3 335
  • 正文 我和宋清朗相戀三年芹壕,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了汇四。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,841評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡踢涌,死狀恐怖通孽,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情睁壁,我是刑警寧澤背苦,帶...
    沈念sama閱讀 35,569評(píng)論 5 345
  • 正文 年R本政府宣布互捌,位于F島的核電站,受9級(jí)特大地震影響行剂,放射性物質(zhì)發(fā)生泄漏秕噪。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評(píng)論 3 328
  • 文/蒙蒙 一厚宰、第九天 我趴在偏房一處隱蔽的房頂上張望腌巾。 院中可真熱鬧,春花似錦固阁、人聲如沸壤躲。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,783評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)碉克。三九已至,卻和暖如春并齐,著一層夾襖步出監(jiān)牢的瞬間漏麦,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,918評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工况褪, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留撕贞,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,962評(píng)論 2 370
  • 正文 我出身青樓测垛,卻偏偏與公主長(zhǎng)得像捏膨,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子食侮,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容