【PlayWright教程(三)】基础操作汇总

这篇博客介绍了Playwright如何进行页面导航、等待策略、元素操作、数据获取以及选择器的使用。它还强调了Playwright在处理网络请求、复用Cookies、设置代理和录制操作方面的便捷性,特别适合爬虫和自动化测试。此外,文章提到了Playwright的命令行工具,能将操作录制成代码。

(后续再补充)

页面基本操作

Navigations | Playwright 中文文档 | Playwright 中文网

按照官网文档,调用 page.goto(url) 后页面加载过程:

  1. 设定 url
  2. 通过网络加载解析页面
  3. 触发 page.on("domcontentloaded") 事件
  4. 执行页面的 js 脚本,加载静态资源
  5. 触发 page.on("laod") 事件
  6. 页面执行动态加载的脚本
  7. 当 500ms 都没有新的网络请求的时候,触发 networkidle 事件

page.goto(url) 会跳转到一个新的链接。默认情况下 Playwright 会等待到 load 状态。如果我们不关心加载的 CSS 图片等信息,可以改为等待到 domcontentloaded 状态,如果页面是 ajax 加载,那么我们需要等待到 networkidle 状态。如果 networkidle 也不合适的话,可以采用 page.wait_for_selector 等待某个元素出现。不过对于 click 等操作会自动等待。

page.goto(url, referer="", timeout=30, wait_until="domcontentloaded|load|networkidle")

// Navigate and wait until network is idle
await page.goto('https://example.com', { waitUntil: 'networkidle' });

Playwright 会自动等待元素处于可操作的稳定状态。当然也可以用 page.wait_for_* 函数来手工等待:

page.wait_for_event("event", event_predict, timeout)
page.wait_for_function(js_function)
page.wait_for_load_state(state="domcontentloaded|load|networkidle", timeout)
page.wait_for_selector(selector, timeout)
page.wait_for_timeout(timeout)  # 不推荐使用

对页面的操作方法主要有:

# selector 指的是 CSS 等表达式
page.click(selector)
page.fill(selector, value)  # 在 input 中填充值

# 例子
page.click("#search")

获取页面中的数据的主要方法有:

page.url  # url
page.title()  # title
page.content()  # 获取页面全文
page.inner_text(selector)  # element.inner_text()
page.inner_html(selector)
page.text_content(selector)
page.get_attribute(selector, attr)

# eval_on_selector 用于获取 DOM 中的值
page.eval_on_selector(selector, js_expression)
# 比如:
search_value = page.eval_on_selector("#search", "el => el.value")

# evaluate 用于获取页面中 JS 中的数据,比如说可以读取 window 中的值
result = page.evaluate("([x, y]) => Promise.resolve(x * y)", [7, 8])
print(result) # prints "56"

选择器表达式

在上面的代码中,我们使用了 CSS 表达式(比如#button)来选取元素。实际上,Playwright 还支持 XPath 和自己定义的两种简单表达式,并且是自动识别的。

# 通过文本选择元素,这是 Playwright 自定义的一种表达式
page.click("text=login")

# 直接通过 id 选择
page.click("id=login")

# 通过 CSS 选择元素
page.click("#search")
# 除了常用的 CSS 表达式外,Playwright 还支持了几个新的伪类
# :has 表示包含某个元素的元素
page.click("article:has(div.prome)")
# :is 用来对自身做断言
page.click("button:is(:text('sign in'), :text('log in'))")
# :text 表示包含某个文本的元素
page.click("button:text('Sign in')")  # 包含
page.click("button:text-is('Sign is')")  # 严格匹配
page.click("button:text-matches('\w+')")  # 正则
# 还可以根据方位匹配
page.click("button:right-of(#search)")  # 右边
page.click("button:left-of(#search)")  # 左边
page.click("button:above(#search)")  # 上边
page.click("button:below(#search)")  # 下边
page.click("button:near(#search)")  # 50px 之内的元素

# 通过 XPath 选择
page.click("//button[@id='search'])")
# 所有 // 或者 .. 开头的表达式都会默认为 XPath 表达式

对于 CSS 表达式,还可以添加前缀css=来显式指定,比如说 css=.login 就相当于 .login.

除了上面介绍的四种表达式以外,Playwright 还支持使用 >> 组合表达式,也就是混合使用四种表达式。

page.click('css=nav >> text=Login')

复用 Cookies 等认证信息

在 Puppeteer 中,复用 Cookies 也是一个老大难问题了。这个是 Playwright 特别方便的一点,他可以直接导出 Cookies 和 LocalStorage, 然后在新的 Context 中使用。

# 保存状态
import json
storage = context.storage_state()
with open("state.json", "w") as f:
    f.write(json.dumps(storage))

# 加载状态
with open("state.json") as f:
    storage_state = json.loads(f.read())
context = browser.new_context(storage_state=storage_state)

监听事件

通过 page.on(event, fn) 可以来注册对应事件的处理函数:

def log_request(intercepted_request):
    print("a request was made:", intercepted_request.url)
page.on("request", log_request)
# sometime later...
page.remove_listener("request", log_request)

其中比较重要的就是 request 和 response 两个事件

拦截更改网络请求

可以通过 page.on("request") 和 page.on("response") 来监听请求和响应事件。

from playwright.sync_api import sync_playwright as playwright

def run(pw):
    browser = pw.webkit.launch()
    page = browser.new_page()
    # Subscribe to "request" and "response" events.
    page.on("request", lambda request: print(">>", request.method, request.url))
    page.on("response", lambda response: print("<<", response.status, response.url))
    page.goto("https://example.com")
    browser.close()

with playwright() as pw:
    run(pw)

其中 request 和 response 的属性和方法,可以查阅文档:https://playwright.dev/python/docs/api/class-request

通过 context.route, 还可以伪造修改拦截请求等。比如说,拦截所有的图片请求以减少带宽占用:

context = browser.new_context()
page = context.new_page()
# route 的参数默认是通配符,也可以传递编译好的正则表达式对象
context.route("**/*.{png,jpg,jpeg}", lambda route: route.abort())
context.route(re.compile(r"(\.png$)|(\.jpg$)"), lambda route: route.abort())
page.goto("https://example.com")
browser.close()

其中 route 对象的相关属性和方法,可以查阅文档:https://playwright.dev/python/docs/api/class-route

灵活设置代理

Playwright 还可以很方便地设置代理。Puppeteer 在打开浏览器之后就无法在更改代理了,对于爬虫类应用非常不友好,而 Playwright 可以通过 Context 设置代理,这样就非常轻量,不用为了切换代理而重启浏览器。

context = browser.new_context(
    proxy={"server": "http://example.com:3128", "bypass": ".example.com", "username": "", "password": ""}
)

杀手级功能:录制操作直接生成代码

Playwright 的命令行还内置了一个有趣的功能:可以通过录制你的点击操作,直接生成 Python 代码。

python -m playwright codegen http://example.com/

Playwright 还有很多命令行功能,比如生成截图等等,可以通过 python -m playwright -h 查看。

其他

除此之外,Playwright 还支持处理页面弹出的窗口,模拟键盘,模拟鼠标拖动(用于滑动验证码),下载文件等等各种功能,请查看官方文档吧,这里不赘述了。对于写爬虫来说,Playwright 的几个特性可以说是秒杀 Puppeteer/Pyppeteer:

  1. 官方同步版本的 API
  2. 方便导入导出 Cookies
  3. 轻量级设置和切换代理
  4. 支持丰富的选择表达式

参考:

Playwright: 比 Puppeteer 更好用的浏览器自动化工具 - 知乎

### Playwright 使用指南及相关常见问题 #### 什么是 PlaywrightPlaywright 是一种用于自动化控制现代浏览器的强大工具,支持 Chromium、Firefox 和 WebKit 等多种浏览器引擎。它不仅适用于测试场景,还可以用来抓取网页数据或模拟复杂的用户交互行为[^1]。 --- #### 如何安装 Playwright? 要开始使用 Playwright,需先完成以下步骤: 1. **确保环境准备就绪** 需要安装 Node.js 并验证其版本是否满足最低要求。可通过 `node -v` 命令检查当前系统的 Node.js 版本。 2. **安装 Playwright 及依赖项** 对于 Python 用户,可以直接通过 pip 安装 Playwright 的 Python SDK: ```bash pip install playwright ``` 接着初始化所需的支持浏览器组件: ```bash playwright install ``` 3. **针对特定需求自定义安装** 如果只需要某些特定的浏览器(如 Firefox),可以指定安装目标: ```bash playwright install firefox ``` 以上过程涵盖了基本的安装流程[^3]。 --- #### Playwright 的核心功能与特性 以下是 Playwright 提供的一些主要特性和优势: 1. **跨平台兼容性** 支持主流浏览器引擎(Chromium、Firefox 和 WebKit),能够覆盖更广泛的测试范围和真实用户体验仿真[^1]。 2. **强大的选择器机制** Playwright 内置了灵活的选择器策略,允许开发者轻松定位页面上的任何元素。例如,CSS 选择器、XPath 表达式甚至基于文本的内容匹配均可作为选项之一[^2]。 3. **内置超时保护机制** 执行每一步操作前都会自动检测条件是否成熟;如果超过设定的时间限制仍未达成,则抛出 TimeoutError 异常提示错误位置以便调试[^4]。 4. **异步编程模型** 利用 Python 中的协程技术实现高效的并发处理能力,尤其适合大规模批量任务调度或者长时间运行的任务管理[^2]。 --- #### 创建第一个简单的 Playwright 脚本实例 下面展示了一个完整的入门级脚本样例,演示如何访问网站并截屏保存图片文件: ```python from playwright.sync_api import sync_playwright def run(playwright): browser = playwright.chromium.launch(headless=False) # 启动带界面模式下的 Chrome 浏览器 context = browser.new_context() # 开启新标签页加载 Google 主页 page = context.new_page() page.goto("https://www.google.com") # 截图存储至本地磁盘路径下 page.screenshot(path="google_homepage.png") # 清理资源退出程序 context.close() browser.close() with sync_playwright() as pw: run(pw) ``` 此代码片段展示了同步方式调用 API 进行基础浏览活动的过程[^1]。 对于需要更高性能的应用场合,则推荐采用异步风格编写逻辑结构更加清晰简洁高效可靠的解决方案如下所示: ```python import asyncio from playwright.async_api import async_playwright async def main(): async with async_playwright() as p: device_descriptor = p.devices["iPhone X"] # 模拟 iPhone 设备参数 browser = await p.webkit.launch() # 启动 Webkit 浏览器 context = await browser.new_context( **device_descriptor, locale='zh-CN', timezone_id='Asia/Shanghai' ) page = await context.new_page() await page.goto('http://example.com') content = await page.content() # 获取整个 HTML 文档字符串形式表示 print(content[:50]) # 输出部分源码预览 await browser.close() if __name__ == "__main__": asyncio.run(main()) ``` 上述例子说明了如何利用设备描述符来模仿移动客户端的行为特征,并且提取远程服务器返回的数据内容进行进一步分析加工处理[^2]。 --- #### 常见问题解答 (FAQs) ##### Q: 怎么解决 “No browsers installed” 错误消息? A: 当首次尝试运行 Playwright 应用却收到此类警告信息时表示尚未下载对应的目标浏览器包体,请按照官方指引重新执行安装命令即可修复该状况。具体做法参阅前述章节关于安装的部分介绍[^3]。 ##### Q: 是否存在替代方案代替默认关闭行为? A: 默认情况下一旦超出作用域范围之外所有关联的对象都将被销毁回收掉内存空间从而终止相应服务连接状态。但如果希望保留持久化链接则应该改用 `.start()` 方法手动获取全局可用实例句柄而不是依靠上下文管理器语法糖封装好的临时局部变量副本[^2]. ---
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值