简写
click()
page.click("//input[@type='submit']")
fill()
page.locator("input[name=\"login_code\"]").fill("4121")
page.fill("input[name=\'login_code\']", "4121")
等待元素
.wait_for()
page.locator("text=example domain").wait_for(state="visible")
# 参数:state="visible"
state = ''
'attached' - 等待元素出现在 DOM 中
'detached' - 等待元素不存在于 DOM 中
'visible' - 等待元素可见
'hidden' - 等待元素隐藏
跳转页面
goto()
#### wait_until=""
等待网络加载完成
page.goto("https://example.com", wait_until="networkidle")
模拟真实键盘输入
.tpye()
page.type("#kw", "playwright", delay=100) # : 每个字符延迟100ms输入
链式选择器
选择器可以与>>
组合使用,例如selector1 >> selector2 >> selectors3
。当选择器被链接时,下一个选择器会相对于前一个选择器的结果进行查询。
page.querySelector('css=article >> css=.bar > .baz >> css=span[attr=value]')
相当于
page.querySelector('article').querySelector('.bar > .baz').querySelector('span[attr=value]')
多元素的首尾元素
应用场景:我添加一个东西,这时候用first就可以直接定位到我增加的元素上,此时就能快速的操作了 。
.first
# 获取多个元素的第一个
page.locator(".box_act").first.click()
.last
page.locator(".box_act").last.click()
注意:尽量从主模块找元素
文本选择
text=
page.click("text=Log in")
事件监听
page.on()
监听到事件以后,出发其他函数
from playwright.sync_api import sync_playwright
def on_response(response):
if '/api/movie/' in response.url and response.status == 200:
print(response.json())
with sync_playwright() as p:
browser = p.chromium.launch(headless=False)
page = browser.new_page()
page.on('response', on_response)
page.goto('https://spa6.scrape.center/')
page.wait_for_load_state('networkidle')
browser.close()
等待时间
强制等待
page.wait_for_timeout(1000)
自动等待
.wait_for_selector()
- 等待元素可见
li = page.wait_for_selector("//span[@class='set']", state="visible") # 默认
- 等待元素变得不可见,例如通过'display:none'
li = page.wait_for_selector("//span[@class='set']", state='hidden')
- 等待元素出现在DOM中
li = page.wait_for_selector("//span[@class='set']", state='attached')
- 等待从DOM中移除
li = page.wait_for_selector("//span[@class='set']", state='detached')
等待事件被触发
.wait_for_load_state()
等待前面按钮触发的事件加载完成,才进行下面的操作
"load" - 默认
page.locator("text=课题研究").click()
page.wait_for_load_state()
page.locator(".main_top_button .button_top_1").click() # 点击创建课题
等到没有网络连接至少毫秒。`500`
"networkidle"
page.wait_for_load_state("networkidle")
弹窗处理
.expect_popup()
with page.expect_popup() as popup_info:
page.click("#open")
popup = popup_info.value
popup.wait_for_load_state()
print(popup.title())
frame框架
.frame()
# 通过frame的name属性
frame = page.frame('innerFrame')
# 通过frame的url属性
frame = page.frame(url='sample1.html')
# 通过选择器获取frame
frame_element = page.query_selector('#frame1')
frame = frame_element.content_frame()
frame.fill('#searchtext', 'baiye')
开新tab页操作
context.expect_page()
def run(playwright: Playwright) -> None:
browser = playwright.chromium.launch(headless=False)
context = browser.new_context()
page = context.new_page()
page.goto("https://cn.bing.com/search?q=百度")
with context.expect_page() as new_page_info:
page.click("text=百度一下,你就知道")
new_page = new_page_info.value # 返回一个新页面
new_page.fill('#kw', '上海')
time.sleep(3)
# ---------------------
context.close()
browser.close()
with sync_playwright() as playwright:
run(playwright)
重定向
等待主框架导航并返回主资源响应。在多次重定向的情况下,导航将通过最后一次重定向的响应来解决
.expect_navigation()
例一
# 默认等待30秒
with page.expect_navigation():
page.goto('https://cdn2.byhy.net/files/selenium/sample2.html')
例二:
# 直到跳转到这个url地址页面为止
with page.expect_navigation(url='https://cdn2.byhy.net/files/selenium/sample2.html'):
page.goto('https://cdn2.byhy.net/files/selenium/sample2.html')
上传文件
.set_files()
点击上传
with page.expect_file_chooser() as fc_info:
page.click("svg._load-icon_k3xef_85")
file_chooser = fc_info.value
file_chooser.set_files(r"D:\Downloads\132007.jpg")
- 下载和上传的区别就是必须要引入上下文,官网提供的上下文就是使用
browser.new_context(accept_downloads=True)
,方法的括号中必须要有accept_downloads=True
,不然运行就会报错。 expect_download
方法是官方提供的下载方法,不作过多解释,用就是了download_info.value
是获取到了上传的相关元素,然后赋值给download
获取页面地址
.url
page.goto(page.url)
print(page.url)
滚动条
.scroll_into_view_if_needed()
SDetail.page.locator("ul.custom").scroll_into_view_if_needed()
刷新页面
.reload()
page.reload()
提取标签
.query_selector()
elements = page.query_selector("//span[@class='title-content-title']")
注意:多个标签,取第一个标签
.query_selector_all()
elements = page.query_selector_all("//span[@class='title-content-title']")
for i in elements:
er = i.text_content()
print(er)
[<JSHandle preview=JSHandle@node>, <JSHandle preview=JSHandle@node>]
JS句柄
获取元素文本
.text_content()
获取文本内容
elements = page.query_selector("//span[@class='title-content-title']").text_content()
简写
elements = page.text_content("//span[@class='title-content-title']")
.inner_text()
获取内部文本值
elements = page.query_selector("//span[@class='title-content-title']").inner_text()
简写
elements = page.inner_text("//span[@class='title-content-title']")
提取元素属性
.get_attribute()
# 以提取class属性值为例
link = page.query_selector("//span[@class='title-content-title']").get_attribute("class")
元素判断(.is_***)
元素判断,是不会去等待的
.is_visible()
- 返回值为bool
- 判断元素是否可见
visible = self.page.is_visible("id=su")
.is_enabled()
- 判断元素是否可用
- 返回值为bool
enabled = self.page.is_enabled("id=su")
获取页面源码
.content()
html = page.content()
print(html)
选择框
.check()
# 选中
page.check("#s_checkbox input[value='小雷老师']")
.uncheck()
# 不选中
page.uncheck("#s_checkbox input[value='小雷老师']")
下拉框
.select_option()
单选
# selecor, value
page.select_option("#ss_single", '小雷老师')
多选
# <select>, list的属性value
page.select_option("#ss_multi", ['小凯老师', '小雷老师', '小江老师'])
通过选择元素选择
# selecor, 文本
page.query_selector("select[id='ss_single']").select_option('小雷老师')
cookie
.storage_state()
获取cookie
# 获得登录后 cookie
# 保存状态文件
storage = context.storage_state(path=r"F:\PcStudent\playwright\data\Cookie.json")
cookie加载
# 加载cookie
with open("state.json") as f:
storage_state = json.loads(f.read())
context1 = browser.new_context(storage_state=storage_state)
page1 = context1.new_page()
page1.goto("http://test.mediolabs.com/Case/CaseManage/_login")
storage1 = context1.storage_state()
执行js
.evaluate()
先定位到元素后再进行js操作:
page.goto("https://www.baidu.com/")
input_handle = page.query_selector("id=kw")
input_handle.evaluate('node => node.value = "test"')
text = input_handle.evaluate('node => node.value') # 读取输入的值
print(text)
例二:
显现隐藏按钮
del_handle = page.query_selector('a.box_delete') # 获得的是句柄
del_handle.evaluate("document.querySelector('a.box_delete').style.display='block'")
例三:
同理
headle = page.locator(".soutu-hover-tip") # 选中该元素
headle.evaluate("document.querySelector('.soutu-hover-tip').style.display='inline'")
#### 显示所有隐藏元素
handle = self.page.query_selector(".main_body a.box_delete")
handle.evaluate("""
var x = document.querySelectorAll('.main_body a.box_delete');
for (var i = 0; i<x.length; i++){
x[i].style.display = "block";
}
""")
js滚轮
document.documentElement.scrollTop=15000;
悬停
.hover()
page.hover('.soutu-btn')
截图
.screenshot()
page.screenshot(path="screenshot.png")
获取鼠标坐标
.bounding_box()
elem = page.query_selector('#su')
s = elem.bounding_box()
# 结果
{'x': 859, 'y': 188.390625, 'width': 108, 'height': 44}
模拟鼠标
.wheel()滚轮
page.mouse.wheel(0, 7000)
模拟键盘
.keyboard
page.keyboard.up()
page.keyboard.press('d') # 按下抬起
page.keyboard.down('d') # 按下
page.keyboard.up('d') # 抬起
.press()
page.locator("textarea[name=\"text_area\"]").press("Enter")
简写
pgae.press("#kw", "Enter")
模拟箭头
self.page.locator("input[name=\"wd\"]").press("ArrowUp")
self.page.locator("input[name=\"wd\"]").press("ArrowDown")
self.page.locator("input[name=\"wd\"]").press("ArrowLeft")
self.page.locator("input[name=\"wd\"]").press("ArrowRight")
键盘输入技巧
page.locator("textarea[name=\"text_area\"]").fill("E")
page.locator("textarea[name=\"text_area\"]").press("Enter")
page.locator("textarea[name=\"text_area\"]").fill("R")
page.locator("textarea[name=\"text_area\"]").press("Enter")
page.locator("textarea[name=\"text_area\"]").press("T")
相当于
page.locator("textarea[name=\"text_area\"]").fill("E\nR\nT")