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有三种方法:
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()
参考
作者:liu_lucas
出处:https://www.cnblogs.com/lucas--liu/
感谢您的阅读,如果您觉得本文对您有帮助,请点击一下"推荐"按钮;如果有错误,欢迎留言指正,谢谢。
版权声明:本文欢迎转载,但是转载文章之后必须在文章明显位置注明出处,否则保留追究法律责任的权力。
出处:https://www.cnblogs.com/lucas--liu/
感谢您的阅读,如果您觉得本文对您有帮助,请点击一下"推荐"按钮;如果有错误,欢迎留言指正,谢谢。
版权声明:本文欢迎转载,但是转载文章之后必须在文章明显位置注明出处,否则保留追究法律责任的权力。