@[toc]
Playwright 的 page.on() 方法用于监听页面的各种事件。这是一个非常强大的功能,可以监听网络请求、对话框、控制台消息等。
基本语法
python
page.on(event, callback)
常用事件类型
1. 监听网络请求
python
async def handle_request(request):
print(f"请求: {request.method} {request.url}")
async def handle_response(response):
if response.status == 200:
print(f"响应: {response.status} {response.url}")
# 可以获取响应内容
# body = await response.body()
page.on("request", handle_request)
page.on("response", handle_response)
2. 监听对话框
python
async def handle_dialog(dialog):
print(f"对话框类型: {dialog.type}")
print(f"对话框消息: {dialog.message}")
await dialog.accept() # 接受对话框
# 或者 await dialog.dismiss() # 关闭对话框
page.on("dialog", handle_dialog)
3. 监听控制台消息
python
async def handle_console(msg):
print(f"控制台 {msg.type}: {msg.text}")
if msg.type == 'error':
print(f"错误详情: {msg.location}")
page.on("console", handle_console)
4. 监听页面错误
python
async def handle_page_error(error):
print(f"页面错误: {error}")
page.on("pageerror", handle_page_error)
完整示例
python
import asyncio
from playwright.async_api import async_playwright
async def main():
async with async_playwright() as p:
browser = await p.chromium.launch(headless=False)
page = await browser.new_page()
# 设置事件监听器
async def handle_request(request):
if request.resource_type == "xhr" or request.resource_type == "fetch":
print(f"API请求: {request.method} {request.url}")
async def handle_response(response):
if response.status == 200 and "api" in response.url:
print(f"API响应: {response.status} {response.url}")
try:
json_data = await response.json()
print(f"响应数据: {json_data}")
except:
pass
async def handle_console(msg):
if msg.type in ['error', 'warning']:
print(f"控制台{msg.type}: {msg.text}")
async def handle_dialog(dialog):
print(f"弹出对话框: {dialog.message}")
await dialog.accept()
# 注册事件监听器
page.on("request", handle_request)
page.on("response", handle_response)
page.on("console", handle_console)
page.on("dialog", handle_dialog)
# 导航到页面
await page.goto("https://example.com")
# 执行一些操作
await page.click("button")
await asyncio.sleep(5)
await browser.close()
# 运行
asyncio.run(main())
实际应用场景
场景1:拦截和修改请求
python
async def handle_request(request):
# 拦截图片请求
if request.resource_type == "image":
await request.abort()
# 修改请求头
elif "api" in request.url:
headers = request.headers
headers['Authorization'] = 'Bearer token'
await request.continue_(headers=headers)
else:
await request.continue_()
await page.route("**/*", handle_request)
场景2:收集性能数据
python
responses = []
async def handle_response(response):
if response.status == 200:
timing = await response.request.timing()
responses.append({
'url': response.url,
'status': response.status,
'size': len(await response.body()),
'timing': timing
})
page.on("response", handle_response)
场景3:自动处理弹窗
python
async def handle_dialog(dialog):
print(f"自动处理对话框: {dialog.message}")
await dialog.accept()
page.on("dialog", handle_dialog)
移除事件监听器
python
# 移除特定事件的所有监听器
page.remove_listener("request", handle_request)
# 或者重新定义为一个空函数
async def empty_handler():
pass
page.on("request", empty_handler)
注意事项
- 异步处理:所有事件处理函数都必须是异步的
- 性能影响:大量的事件监听可能会影响性能
- 内存泄漏:长时间运行的页面要注意移除不需要的监听器
- 错误处理:在事件处理函数中要做好异常处理
常用事件列表
| 事件类型 | 描述 |
|---|---|
request |
发送网络请求时 |
response |
收到网络响应时 |
dialog |
出现JavaScript对话框时 |
console |
控制台输出消息时 |
pageerror |
页面发生JavaScript错误时 |
load |
页面加载完成时 |
domcontentloaded |
DOM内容加载完成时 |
framenavigated |
框架导航完成时 |
使用 page.on() 可以让你更好地监控和控制页面的行为,特别是在调试和自动化测试中非常有用。