页面导航
简介
Playwright 可以导航到指定 URL 并处理由页面交互引发的导航操作。
基础导航
最简单的导航形式是打开一个 URL:
// 导航页面
await page.goto('https://example.com');
上述代码会加载页面并等待网页触发 load 事件。load 事件会在整个页面及其所有依赖资源(如样式表、脚本、iframe 和图片)加载完成后触发。
:::注意
如果页面在 load
事件前进行了客户端重定向,page.goto() 会等待重定向后的页面触发 load
事件。
:::
页面何时算加载完成?
现代页面在 load
事件触发后还会执行大量操作。它们会延迟加载数据、填充 UI、在 load
事件后加载昂贵的资源、脚本和样式。无法确切判断页面是否"加载完成",这取决于具体页面、框架等因素。那么何时可以开始与页面交互呢?
在 Playwright 中,您可以随时与页面交互。它会自动等待目标元素变为可操作状态。
// 导航并点击元素
// 点击操作会自动等待元素就绪
await page.goto('https://example.com');
await page.getByText('Example Domain').click();
对于上述场景,Playwright 会等待文本可见,等待该元素通过所有可操作性检查,然后执行点击操作。
Playwright 的操作速度非常快——它一看到按钮就会立即点击。在大多数情况下,您无需担心所有资源是否已加载等问题。
水合作用
在某些情况下,你可能会遇到这样的场景:Playwright 执行了某个操作,但表面上没有任何反应。或者你在输入框中输入了文本,但它却消失了。这最可能的原因是页面水合作用处理不当。
当页面进行水合时,首先会向浏览器发送页面的静态版本。然后发送动态部分,使页面变得"活跃"。作为速度极快的用户,Playwright 会在看到页面的瞬间就开始与之交互。如果页面上的按钮已启用,但监听器尚未添加,Playwright 会执行操作,但点击不会产生任何效果。
验证你的页面是否存在水合问题的一个简单方法是:打开 Chrome DevTools,在 Network 面板中选择"Slow 3G"网络模拟,然后重新加载页面。当你看到感兴趣的元素时,尝试与之交互。你会发现按钮点击会被忽略,输入的文本会被后续的页面加载代码重置。解决这个问题的正确方法是确保所有交互控件在水合完成前保持禁用状态,直到页面完全功能化。
等待导航
点击元素可能会触发多次导航。在这些情况下,建议显式使用 page.waitForURL() 等待特定 URL。
await page.getByText('点击我').click();
await page.waitForURL('**/login');
导航事件
Playwright 将页面中显示新文档的过程分为导航和加载两个阶段。
导航开始于页面 URL 的变更或与页面的交互(例如点击链接)。导航意图可能会被取消,例如在遇到无法解析的 DNS 地址时,或者转变为文件下载。
当响应头被解析且会话历史更新时,导航即被提交。只有在导航成功(被提交)后,页面才会开始加载文档。
加载阶段包括通过网络获取剩余响应体、解析、执行脚本以及触发加载事件:
- page.url() 被设置为新 URL
- 通过网络加载并解析文档内容
- 触发 page.on('domcontentloaded') 事件
- 页面执行部分脚本并加载样式表和图片等资源
- 触发 page.on('load') 事件
- 页面执行动态加载的脚本