Playwright 是微软开发的浏览器自动化工具 ,可以理解为 Python 中 Selenium 的现代替代品。它通过单一 API 支持 Chromium、Firefox 和 WebKit(Safari 内核),并以更稳定、更快速、更简洁著称。
核心优势
| 特性 | Playwright | Selenium |
|---|---|---|
| 安装配置 | 一条命令自动安装浏览器 | 需手动下载驱动并匹配版本 |
| 等待机制 | 自动等待元素可操作 | 需手动添加 time.sleep() |
| 速度 | 更快(基于 WebSocket) | 较慢 |
| API 设计 | 现代化,支持 async/await | 传统同步风格 |
| 移动端模拟 | 原生支持设备模拟 | 需第三方工具 |
快速开始
安装
bash
pip install playwright
playwright install # 安装 Chromium、Firefox、WebKit 浏览器
基础示例
python
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
# 启动浏览器(headless=False 可看到界面)
browser = p.chromium.launch(headless=True)
page = browser.new_page()
# 访问网页
page.goto("https://example.com")
# 截图和获取标题
page.screenshot(path="example.png")
print(page.title())
browser.close()
常用操作
1. 定位元素
python
# 支持多种选择器
page.click("#submit") # CSS选择器
page.fill("input[name='username']", "张三") # 填充输入框
page.get_by_text("登录") # 文本匹配
page.get_by_role("button", name="提交") # ARIA角色
page.locator("div.item").nth(2).click() # 链式操作
2. 等待机制
python
# Playwright 会自动等待元素可操作,无需手动 sleep
page.click("button") # 自动等待按钮可见且启用
# 显式等待特定条件
page.wait_for_selector(".result")
page.wait_for_timeout(1000) # 避免使用,仅在特殊场景
3. 表单操作
python
page.fill("#username", "admin")
page.fill("#password", "123456")
page.check("#agree") # 复选框
page.select_option("#city", "Beijing") # 下拉框
page.click("button[type='submit']")
4. 网络请求拦截
python
def handle_response(response):
if response.url.endswith(".json"):
print(response.json())
page.on("response", handle_response)
page.goto("https://example.com")
异步版本
python
import asyncio
from playwright.async_api import async_playwright
async def main():
async with async_playwright() as p:
browser = await p.chromium.launch()
page = await browser.new_page()
await page.goto("https://example.com")
await browser.close()
asyncio.run(main())
高级特性
1. 录制操作生成代码
bash
playwright codegen https://example.com
会自动打开浏览器,你的点击、输入操作会被实时转换为 Playwright 代码。
2. 模拟移动设备
python
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
iphone_12 = p.devices["iPhone 12"]
browser = p.chromium.launch()
context = browser.new_context(**iphone_12)
page = context.new_page()
page.goto("https://example.com")
3. 处理多页面
python
with context.expect_page() as new_page_info:
page.click("a[target='_blank']") # 点击打开新标签页的链接
new_page = new_page_info.value
new_page.wait_for_load_state()
print(new_page.title())
4. 文件上传
python
# 方式1:设置文件输入框的值
page.set_input_files("input[type='file']", "document.pdf")
# 方式2:拖拽上传
with page.expect_file_chooser() as fc_info:
page.click("button.upload")
file_chooser = fc_info.value
file_chooser.set_files("image.jpg")
实际爬虫示例
python
from playwright.sync_api import sync_playwright
def get_douban_top250():
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
page = browser.new_page()
movies = []
for start in range(0, 250, 25):
page.goto(f"https://movie.douban.com/top250?start={start}")
# 等待电影列表加载
page.wait_for_selector(".grid_view")
items = page.query_selector_all(".item")
for item in items:
title = item.query_selector(".title").inner_text()
rating = item.query_selector(".rating_num").inner_text()
movies.append({"title": title, "rating": rating})
browser.close()
return movies
print(get_douban_top250()[:5])
对比总结
Playwright 适合:
- 需要稳定抓取动态网站(React/Vue 等)
- 需要自动化测试 Web 应用
- 需要模拟复杂用户交互(键盘、鼠标、触摸)
- 需要多浏览器兼容性测试
不如 Selenium 的场景:
- 需要支持非常老的浏览器(IE 等)
- 团队已有成熟的 Selenium 框架
- 需要集成到某些特定老旧环境
调试技巧
python
# 慢速执行(便于观察)
browser = p.chromium.launch(slow_mo=500)
# 截图调试
page.screenshot(path="debug.png")
# 获取页面 HTML
print(page.content())
# 非 headless 模式运行
browser = p.chromium.launch(headless=False)