wait_for_timeout
page.wait_for_timeout()
# 用于让脚本执行暂停指定时长的方法 单位是毫秒,在某些页面操作后,可能需要等待一段时间让页面完成加载、数据更新或者动画效果结束等情况,而又不好通过其他更精确的等待条件(如等待某个元素出现、某个网络请求完成等)来判断时,就可以使用 page.wait_for_timeout() 来简单地等待固定时长,确保后续操作是在页面相对稳定的状态下进行的
wait_for_event
用于暂停脚本的执行,直到特定的事件被触发。它允许你等待各种与页面相关的事件,如网络请求完成、元素状态变化(例如变为可见或可点击)、对话框出现等。这对于确保测试脚本在正确的时间执行后续操作很关键,避免因为操作过早或过晚而导致测试失败。
它的基本语法是page.wait_for_event(event_name, **kwargs)。其中event_name是要等待的事件名称,常见的事件名称包括’request’(网络请求)、‘response’(网络响应)、‘load’(页面加载完成)、‘domcontentloaded’(DOM 加载完成)、‘dialog’(对话框出现)等。**kwargs是可选的关键字参数,用于更精确地定义等待事件的条件,例如,对于’request’事件,可以通过url参数指定要等待的请求的 URL 模式。
from playwright.sync_api import sync_playwrightwith sync_playwright() as p:browser = p.chromium.launch()page = browser.new_page()page.goto("https://example.com")# 等待名为'user_data'的网络请求完成with page.wait_for_event('request', predicate=lambda r: 'user_data' in r.url):# 当请求完成后,这里的代码会继续执行print("用户数据请求已完成")browser.close()
在这个示例中,page.wait_for_event(‘request’, predicate=lambda r: ‘user_data’ in r.url)会暂停脚本执行,直到一个 URL 中包含’user_data’的网络请求完成。predicate参数是一个函数,用于定义更具体的等待条件,这里通过检查请求的 URL 是否包含特定字符串来确定是否是我们要等待的请求。
以下是一个等待对话框(如alert、confirm或prompt)出现并处理的示例。
from playwright.sync_api import sync_playwrightwith sync_playwright() as p:browser = p.chromium.launch()page = browser.new_page()page.goto("https://example.com")# 模拟一个操作导致对话框出现page.evaluate("window.alert('这是一个提示对话框')")# 等待对话框出现with page.wait_for_event('dialog') as dialog:# 打印对话框的消息内容print(dialog.message)# 关闭对话框dialog.accept()browser.close()
在这个示例中,首先通过page.evaluate()模拟了一个操作,使页面弹出一个alert对话框。然后page.wait_for_event(‘dialog’)会暂停脚本,直到对话框出现。一旦对话框出现,代码块内的操作会执行,这里打印了对话框的消息并通过dialog.accept()接受(关闭)了对话框
wait_for_function
用于暂停脚本执行,直到满足特定的 JavaScript 函数条件。它主要用于等待页面状态符合预期的情况,这种状态可能是元素属性的改变、某个变量的值变化或者其他通过 JavaScript 代码才能判断的复杂条件。
基本语法是page.wait_for_function(expression, **kwargs)。
expression:这是一个必需的参数,它是一个 JavaScript 表达式或者函数。这个表达式会在浏览器环境中执行,并且应该返回一个布尔值。当表达式返回true时,等待结束,脚本继续执行
**kwargs:这些是可选的关键字参数。其中比较重要的是polling和timeout
olling:用于指定检查表达式是否为真的频率。默认值是raf(requestAnimationFrame),这意味着它会在每个动画帧检查表达式。也可以设置为一个时间间隔(如1000,单位是毫秒,表示每秒检查一次)或者"mutation"(当 DOM 发生变化时检查)等
timeout:用于指定等待的最长时间,单位是毫秒。如果超过这个时间表达式仍然没有返回true,就会抛出一个超时错误。例如,timeout = 5000表示最多等待 5 秒钟。
假设页面上有一个按钮,初始状态是禁用的,在某个异步操作完成后会变为启用状态。我们想要等待按钮变为可用后再点击它。
from playwright.sync_api import sync_playwrightwith sync_playwright() as p:browser = p.chromium.launch()page = browser.new_page()page.goto("https://example.com")button = page.get_by_role('button')# 等待按钮变为可用page.wait_for_function("arguments[0].disabled === false", args=[button])button.click()browser.close()
在这个示例中,page.wait_for_function(“arguments[0].disabled === false”, args=[button])会暂停脚本,直到通过get_by_role(‘button’)获取的按钮元素的disabled属性变为false(即变为可用)。args参数用于将 Python 中的button元素传递给 JavaScript 表达式,在 JavaScript 中可以通过arguments[0]访问这个元素。
假设页面的 JavaScript 代码中有一个全局变量isDataLoaded,初始值为false,当某个数据加载操作完成后会变为true。我们想要等待这个变量变为true后再进行验证操作。
from playwright.sync_api import sync_playwrightwith sync_playwright() as p:browser = p.chromium.launch()page = browser.new_page()page.goto("https://example.com")# 等待变量isDataLoaded变为truepage.wait_for_function("window.isDataLoaded === true")# 进行数据验证操作,例如检查页面上某个数据显示区域是否有内容data_area = page.get_by_role('div', name='数据显示区域')assert data_area.inner_text()!= ""browser.close()
在这里,page.wait_for_function(“window.isDataLoaded === true”)会等待window.isDataLoaded变量变为true,一旦满足这个条件,就会继续执行后面的数据验证操作,检查名为 “数据显示区域” 的div元素是否有内容。
浏览器的 document.readyState 属性直接用于判断页面加载状态的属性。它有三个可能的值 ‘loading’:文档正在加载。‘interactive’:文档已经被解析完成,DOM 树已经构建,但是像图像、样式表等外部资源可能还在加载。‘complete’:文档和所有的子资源都已经加载完成。通过检查document.readyState的值是否为’complete’来确定页面是否加载完成
wait_for_selector
是一个用于等待特定 CSS 选择器所匹配的元素出现在页面中的方法。它在自动化测试和网页爬取等场景中非常有用,确保在对某个元素进行操作(如点击、获取文本内容等)之前,该元素已经在页面中成功加载并可被访问。
基本语法为page.wait_for_selector(selector, **kwargs)。
selector:这是一个必需的参数,用于指定要等待的元素的 CSS 选择器。例如,‘button#submit’表示等待id为submit的按钮元素,’.class-name’表示等待具有特定类名的元素。
**kwargs:这些是可选的关键字参数,包括:
1 state:用于指定元素的期望状态,有三个可选值:‘attached’(默认值,元素出现在 DOM 中即可)、‘visible’(元素不仅要在 DOM 中,还要在页面上可见,即display属性不能为none,并且元素及其祖先元素的visibility属性不能为hidden)和’detached’(等待元素从 DOM 中移除)
2 timeout:用于指定等待的最长时间,单位是毫秒。如果在超时时间内元素没有达到期望的状态,会抛出一个TimeoutError。例如,timeout = 5000表示最多等待 5 秒钟。
假设页面加载后会异步加载一个按钮,我们需要等待这个按钮出现后再点击它。
from playwright.sync_api import sync_playwrightwith sync_playwright() as p:browser = p.chromium.launch()page = browser.new_page()page.goto("https://example.com")# 等待按钮出现并点击button_selector = 'button#submit'button = page.wait_for_selector(button_selector)button.click()browser.close()
在这个示例中,page.wait_for_selector(‘button#submit’)会暂停脚本执行,直到id为submit的按钮元素出现在页面的 DOM 中。一旦按钮出现,就会获取这个元素并通过button.click()进行点击操作。
假设页面上有一个初始为隐藏状态的元素,在某个操作后会变为可见,我们要等待它可见后获取其文本内容。
from playwright.sync_api import sync_playwrightwith sync_playwright() as p:browser = p.chromium.launch()page = browser.new_page()page.goto("https://example.com")# 等待元素变为可见并获取文本element_selector = '.visible-element'visible_element = page.wait_for_selector(element_selector, state='visible')text_content = visible_element.inner_text()print(text_content)browser.close()
在这里,page.wait_for_selector(‘.visible-element’, state=‘visible’)会等待具有.visible-element类名的元素不仅出现在 DOM 中,而且在页面上变为可见。然后获取这个可见元素的inner_text并打印出来。
wait_for_load_state
用于等待页面达到特定的加载状态。它允许你暂停脚本的执行,直到页面的加载过程满足你期望的阶段,例如等待页面完全加载(包括所有资源)、等待页面仅完成 DOM 的加载,或者等待页面变为网络空闲状态等。这在自动化测试和网页操作中非常重要,确保后续的页面操作是在合适的加载阶段进行
基本语法是page.wait_for_load_state(state, **kwargs)
state:这是一个必需的参数,用于指定要等待的页面加载状态。它有以下几个常见的值:
1 'load':等待页面及其所有子资源(如图像、样式表、脚本等)都已加载完成。这类似于浏览器的window.onload事件被触发后的状态。
2 'domcontentloaded':等待 DOM(文档对象模型)已经加载并解析完成,此时 HTML 文档结构已经构建好,但外部资源(如图像、样式表等)可能仍在加载。这类似于浏览器的DOMContentLoaded事件被触发后的状态。
3 'networkidle':等待网络处于空闲状态,即没有超过指定时长(默认是 500 毫秒)的网络请求正在进行。这个状态对于确保页面在相对稳定的网络环境下进行操作很有用,例如在进行截图或者检查页面最终状态时。
**kwargs:这些是可选的关键字参数,其中比较重要的是timeout。timeout用于指定等待的最长时间,单位是毫秒。如果超过这个时间页面还没有达到期望的加载状态,就会抛出一个TimeoutError。例如,timeout = 10000表示最多等待 10 秒钟。
等待页面完全加载后进行操作
from playwright.sync_api import sync_playwrightwith sync_playwright() as p:browser = p.chromium.launch()page = browser.new_page()page.goto("https://example.com")# 等待页面完全加载(包括所有资源)page.wait_for_load_state("load")# 进行页面操作,如获取元素并验证内容element = page.get_by_role("heading", level=1)assert element.inner_text() == "预期的标题内容"browser.close()
在这个示例中,page.wait_for_load_state(“load”)会暂停脚本,直到页面及其所有子资源都加载完成。之后,通过page.get_by_role(“heading”, level=1)获取一级标题元素,并验证其内部文本内容是否符合预期。
等待 DOM 加载完成后操作
from playwright.sync_api import sync_playwrightwith sync_playwright() as p:browser = p.chromium.launch()page = browser.new_page()page.goto("https://example.com")# 等待DOM加载完成page.wait_for_load_state("domcontentloaded")# 检查DOM中是否已经存在某个元素(此时外部资源可能还在加载)element_exists = page.query_selector("body > div#main-content") is not Noneassert element_existsbrowser.close()
这里,page.wait_for_load_state(“domcontentloaded”)等待 DOM 加载并解析完成。然后,通过page.query_selector(“body > div#main-content”)检查页面的body元素下id为main-content的div元素是否已经存在,以此来验证 DOM 加载后的元素是否符合预期。
wait_for_url
是一个用于暂停脚本执行,直到页面导航到符合特定条件的 URL 的方法。它在自动化测试场景中非常有用,特别是当页面存在重定向、通过 JavaScript 进行导航或者多步骤的页面跳转时,能够确保脚本在正确的页面 URL 加载后再继续执行后续操作。
基本语法是page.wait_for_url(url_or_predicate, **kwargs)
url_or_predicate:这是一个必需的参数,可以是以下两种类型:
字符串类型:用于指定要等待的完整 URL 或 URL 模式。例如,https://example.com/new-page是等待页面导航到这个确切的 URL;https://example.com/可以用于等待页面导航到以https://example.com/开头的任何 URL,其中是通配符
函数类型:是一个自定义的判断函数,用于更灵活地判断 URL 是否符合期望。这个函数接受一个url参数,返回一个布尔值。例如,lambda url: “new-page” in url可以用于等待 URL 中包含new - page的页面加载。
**kwargs:这些是可选的关键字参数,主要的是timeout。timeout用于指定等待的最长时间,单位是毫秒。如果超过这个时间页面还没有导航到符合期望的 URL,就会抛出一个TimeoutError。例如,timeout = 7000表示最多等待 7 秒钟。
等待确切的 URL 加载
from playwright.sync_api import sync_playwrightwith sync_playwright() as p:browser = p.chromium.launch()page = browser.new_page()page.goto("https://example.com/start-page")# 模拟点击一个会跳转到新页面的链接link = page.get_by_text("跳转到新页面")link.click()# 等待页面导航到确切的目标URLpage.wait_for_url("https://example.com/new-page")# 验证新页面的内容,如检查标题是否符合预期assert page.title() == "新页面标题"browser.close()
在这个示例中,首先打开起始页面,然后模拟点击一个链接跳转到新页面。page.wait_for_url(“https://example.com/new-page”)会暂停脚本,直到页面导航到https://example.com/new-page这个确切的 URL。之后,通过page.title()验证新页面的标题是否符合预期。
使用 URL 模式等待页面加载
from playwright.sync_api import sync_playwrightwith sync_playwright() as p:browser = p.chromium.launch()page = browser.new_page()page.goto("https://example.com/product-list")# 模拟点击一个产品链接,其URL格式为https://example.com/product/{product - id}product_link = page.get_by_text("产品链接")product_link.click()# 等待页面导航到产品详情页,使用URL模式匹配page.wait_for_url("https://example.com/product/*")# 验证产品详情页的某个元素是否存在,如产品图片product_image = page.get_by_role("img", name="产品图片")assert product_image is not Nonebrowser.close()
在这里,page.wait_for_url(“https://example.com/product/*”)等待页面导航到以https://example.com/product/开头的任何 URL,这符合产品详情页的 URL 模式。然后验证产品详情页的产品图片元素是否存在