python 之playwright 介绍

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)
相关推荐
浪客川2 小时前
【百例RUST - 009】容器 Vector
开发语言·rpc·rust
@不误正业2 小时前
大模型注意力机制源码解析-从MQA到MLA全链路演进与PyTorch实现
人工智能·pytorch·python
weixin_408717772 小时前
CSS如何优化大型项目样式_使用SASS预处理器提升开发效率
jvm·数据库·python
2301_813599552 小时前
CSS如何解决CSS引入后的样式覆盖_理解优先级原则避免重写
jvm·数据库·python
环流_2 小时前
多线程3(线程安全问题及解决方案)
java·开发语言
Li emily2 小时前
外汇api接口实践:实时汇率与历史数据获取
人工智能·python·api·fastapi
weixin_408717772 小时前
PHP8.1新特性对AI开发帮助_JIT编译优势【解答】
jvm·数据库·python
Ares-Wang2 小时前
flask》》多线程并发数据安全问题 threading.local werkzeug.local.Local
后端·python·flask
2401_871696522 小时前
golang如何实现Trie前缀树_golang Trie前缀树实现解析
jvm·数据库·python