Playwright全面教程:常用 API 串联与实战指南
大家好,我是jobleap.cn的小九。
Playwright 是微软推出的新一代自动化测试/爬虫框架,支持 Chromium、Firefox、WebKit 三大浏览器,提供同步/异步 API,具备自动等待、强大的元素定位、网络拦截等核心能力。本文将从环境搭建到综合实战,全面串联 Playwright 的常用 API,帮助你快速掌握其核心用法。
一、环境搭建
1. 安装 Playwright 核心库
pip install playwright
2. 安装浏览器驱动
Playwright 需要对应浏览器的驱动文件,执行以下命令自动安装 Chromium、Firefox、WebKit(也可指定单一浏览器):
# 安装所有浏览器
playwright install
# 仅安装 Chromium(常用)
playwright install chromium
3. 验证安装
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(headless=False) # 启动有头浏览器
page = browser.new_page()
page.goto("https://www.baidu.com")
print(page.title()) # 输出:百度一下,你就知道
browser.close()
二、核心概念(必懂)
Playwright 的核心层级关系:Playwright → Browser → BrowserContext → Page
- Browser:浏览器实例(对应真实浏览器进程),支持多浏览器(Chromium/Firefox/WebKit)。
- BrowserContext:浏览器上下文(类似隐身窗口),隔离的环境,一个 Browser 可创建多个 Context。
- Page:页面(对应浏览器标签页),一个 Context 可创建多个 Page。
三、常用 API 详解与实战
1. 浏览器启动与配置(Browser API)
核心方法:playwright.chromium.launch()(Firefox/webkit 同理),常用参数:
headless:是否无头模式(默认 True,无界面)。slow_mo:慢动作执行(单位 ms,便于调试)。args:浏览器启动参数(如窗口大小、禁用图片加载)。timeout:启动超时时间(默认 30000 ms)。
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
# 启动 Chromium 有头模式,窗口大小 1920x1080,慢动作 500ms
browser = p.chromium.launch(
headless=False,
slow_mo=500,
args=["--window-size=1920,1080", "--disable-images"] # 禁用图片加载
)
# 创建上下文(可配置视口、超时、代理等)
context = browser.new_context(
viewport={"width": 1920, "height": 1080},
timeout=10000, # 上下文级别超时
user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0 Safari/537.36"
)
# 创建页面
page = context.new_page()
page.goto("https://www.baidu.com")
# 关闭资源(建议用 with 上下文自动关闭,此处手动演示)
page.close()
context.close()
browser.close()
2. 页面基础操作(Page API)
(1)导航与刷新
goto(url, wait_until):导航到指定 URL,wait_until可选load(页面加载完成)、domcontentloaded(DOM 加载完成)、networkidle(网络空闲)。reload():刷新页面。go_back()/go_forward():前进/后退。
# 导航到百度,等待网络空闲(适合异步加载页面)
page.goto("https://www.baidu.com", wait_until="networkidle")
# 刷新页面
page.reload()
# 后退/前进
page.go_back()
page.go_forward()
# 获取页面信息
print("页面标题:", page.title())
print("页面URL:", page.url)
print("页面内容:", page.content()) # 获取整个页面 HTML
(2)窗口控制
# 设置页面大小
page.set_viewport_size({"width": 1200, "height": 800})
# 最大化窗口
page.set_viewport_size(page.viewport_size()) # 或通过浏览器 args 设置
# 截图(整页/元素)
page.screenshot(path="full_page.png", full_page=True) # 整页截图
page.locator("#su").screenshot(path="button.png") # 元素截图
3. 元素定位(核心)
Playwright 推荐语义化定位(优先)+ CSS/XPath 定位,支持 8 种定位方式,优先级从高到低:
| 定位方式 | API 示例 | 适用场景 |
|---|---|---|
| 按角色(Role) | page.get_by_role("button", name="百度一下") | 按钮、输入框等可访问性元素 |
| 按文本 | page.get_by_text("百度一下") | 固定文本的元素 |
| 按标签(Label) | page.get_by_label("搜索") | 输入框的标签 |
| 按占位符 | page.get_by_placeholder("请输入搜索内容") | 输入框占位符 |
| 按 Alt 文本 | page.get_by_alt_text("百度logo") | 图片元素 |
| 按 Title 属性 | page.get_by_title("百度首页") | 带 title 的元素 |
| 按测试 ID | page.get_by_test_id("search-btn") | 自定义 data-testid 属性 |
| CSS/XPath | page.locator("#kw")/page.locator('//*[@id="kw"]') | 通用定位 |
示例:百度搜索框定位
# 语义化定位(推荐)
search_input = page.get_by_placeholder("请输入搜索内容") # 按占位符
search_btn = page.get_by_role("button", name="百度一下") # 按角色+名称
# CSS 定位(兼容传统方式)
search_input = page.locator("#kw") # ID 选择器
search_btn = page.locator(".btn-self") # 类选择器
# XPath 定位
search_input = page.locator('//input[@id="kw"]')
4. 元素交互(Page/Locator API)
(1)基础交互
fill(text):输入文本(清空原有内容)。type(text, delay):模拟键盘逐字符输入(带延迟)。click():点击元素(自动等待元素可点击)。hover():悬停。dblclick():双击。
# 输入搜索内容(清空原有内容)
search_input.fill("Playwright Python 教程")
# 模拟键盘输入(逐字符,延迟 100ms)
search_input.type("Playwright Python 教程", delay=100)
# 点击搜索按钮
search_btn.click()
# 悬停到导航栏
page.locator("#nav-top").hover()
(2)表单操作
check()/uncheck():勾选/取消复选框。select_option():选择下拉框。press(key):按键操作(如 Enter、Ctrl+A)。
# 复选框
page.locator("#agree").check() # 勾选
page.locator("#agree").uncheck() # 取消
# 下拉框(按值/标签/索引)
page.locator("#city").select_option(value="beijing") # 按值
page.locator("#city").select_option(label="北京") # 按标签
page.locator("#city").select_option(index=0) # 按索引
# 按键操作
search_input.press("Enter") # 按回车搜索
page.press("Ctrl+A") # 全选页面内容
page.press("Backspace") # 删除选中内容
5. 等待机制(避免硬等待)
Playwright 自带自动等待(操作元素时等待元素可见、可操作),也支持手动等待:
(1)显式等待
# 等待元素可见(超时 5 秒)
page.locator("#kw").wait_for(state="visible", timeout=5000)
# 等待元素可点击
page.locator("#su").wait_for(state="enabled")
# 等待页面加载状态
page.wait_for_load_state("networkidle")
# 等待自定义条件(如标题包含指定内容)
page.wait_for_function("document.title.includes('Playwright')")
(2)超时配置
# 页面级别默认超时(所有操作生效)
page.set_default_timeout(5000)
# 单个操作超时(覆盖全局)
page.locator("#kw").click(timeout=3000)
6. 数据提取
(1)元素数据提取
# 获取元素文本(含隐藏文本)
text = page.locator("h3").first.text_content()
# 获取可见文本
visible_text = page.locator("h3").first.inner_text()
# 获取属性值
href = page.locator("a").first.get_attribute("href")
# 获取所有匹配元素的文本列表
all_titles = page.locator("h3").all_text_contents()
print("所有标题:", all_titles)
(2)录屏(需上下文配置)
# 创建上下文时指定录屏目录
context = browser.new_context(record_video_dir="./videos/")
page.goto("https://www.baidu.com")
context.close() # 关闭后自动生成视频文件
7. 网络拦截与请求处理
Playwright 可拦截、修改、模拟网络请求/响应,适用于爬虫反爬、接口测试。
# 拦截所有图片请求(中止加载,提升速度)
def handle_image_route(route):
route.abort() # 中止请求
# 也可模拟响应:route.fulfill(status=200, body="mock image")
page.route("**/*.{png,jpg,jpeg}", handle_image_route)
# 等待特定请求并获取参数
request = page.wait_for_request("https://www.baidu.com/s")
print("请求方法:", request.method)
print("请求参数:", request.post_data)
# 等待特定响应并解析内容
response = page.wait_for_response("https://www.baidu.com/s")
print("响应状态码:", response.status)
print("响应JSON:", response.json()) # 接口返回JSON时解析
8. 多标签页/多上下文操作
(1)多标签页
# 打开新标签页
page1 = context.new_page()
page1.goto("https://www.baidu.com")
page2 = context.new_page()
page2.goto("https://www.github.com")
# 切换标签页
page2.bring_to_front()
# 获取所有标签页
pages = context.pages
print("标签页数量:", len(pages))
(2)多上下文(隔离环境)
# 上下文1:模拟用户A
context1 = browser.new_context()
page1 = context1.new_page()
page1.goto("https://www.taobao.com")
# 上下文2:模拟用户B(隔离Cookie)
context2 = browser.new_context()
page2 = context2.new_page()
page2.goto("https://www.taobao.com")
9. 弹窗处理(Alert/Confirm/Prompt)
Playwright 可监听并处理浏览器原生弹窗:
# 监听 Alert 弹窗(自动接受)
page.on("dialog", lambda dialog: dialog.accept())
# 监听 Confirm 弹窗(根据消息决定接受/取消)
page.on("dialog", lambda dialog: dialog.accept() if "确认" in dialog.message() else dialog.dismiss())
# 监听 Prompt 弹窗(输入内容并接受)
page.on("dialog", lambda dialog: dialog.accept(prompt_text="测试内容"))
# 触发弹窗(演示用)
page.evaluate("alert('这是一个Alert弹窗')")
page.evaluate("confirm('确认删除?')")
page.evaluate("prompt('请输入姓名:')")
四、综合实战:电商商品信息爬取
需求:爬取京东“Python编程书籍”第一个商品的名称、价格、评价数,并截图保存。
from playwright.sync_api import sync_playwright
def crawl_jd_goods():
with sync_playwright() as p:
# 启动浏览器
browser = p.chromium.launch(headless=False, slow_mo=300)
context = browser.new_context(viewport={"width": 1920, "height": 1080})
page = context.new_page()
try:
# 1. 导航到京东首页
page.goto("https://www.jd.com", wait_until="networkidle")
# 2. 搜索商品
search_input = page.get_by_placeholder("家用电器,手机数码,电脑办公")
search_input.fill("Python编程从入门到实践")
search_input.press("Enter")
# 3. 等待搜索结果加载,点击第一个商品
page.wait_for_load_state("networkidle")
first_goods = page.locator(".gl-item .p-name a").first
first_goods.click()
# 4. 切换到商品详情页(新标签页)
page.wait_for_event("popup")
goods_page = context.pages[-1] # 最后一个标签页为详情页
goods_page.bring_to_front()
goods_page.wait_for_load_state("networkidle")
# 5. 提取商品信息(京东标签可能更新,需按需调整)
goods_name = goods_page.locator(".sku-name").inner_text().strip()
goods_price = goods_page.locator(".price").first.inner_text().strip()
comment_count = goods_page.locator("#comment-count").inner_text().strip()
# 6. 输出并截图
print("="*50)
print("商品名称:", goods_name)
print("商品价格:", goods_price)
print("评价数:", comment_count)
print("="*50)
goods_page.screenshot(path="jd_goods.png", full_page=True)
except Exception as e:
print("爬取出错:", e)
finally:
browser.close()
if __name__ == "__main__":
crawl_jd_goods()
五、高级技巧与注意事项
1. 异步 API(适合高并发)
Playwright 支持异步编程,核心替换 sync_playwright 为 async_playwright:
import asyncio
from playwright.async_api import async_playwright
async def async_demo():
async with async_playwright() as p:
browser = await p.chromium.launch(headless=False)
page = await browser.new_page()
await page.goto("https://www.baidu.com")
print(await page.title())
await browser.close()
asyncio.run(async_demo())
2. 反爬规避
- 设置真实
user_agent(上下文配置)。 - 添加随机延迟(
slow_mo或time.sleep,慎用)。 - 使用代理 IP(上下文配置
proxy={"server": "http://ip:port"})。 - 避免高频操作,模拟真人行为(悬停、滚动)。
3. 测试框架集成
Playwright 可与 pytest 集成(pytest-playwright),实现自动化测试:
pip install pytest-playwright
4. 注意事项
- 避免使用
time.sleep,优先用 Playwright 内置等待。 - 元素定位优先语义化方式(
get_by_role),减少 CSS/XPath 维护成本。 - 无头模式下部分页面渲染可能不同,调试时用有头模式。
- 浏览器驱动版本需与 Playwright 版本匹配(
playwright install自动适配)。
六、总结
Playwright 凭借自动等待、跨浏览器、强大的定位与网络拦截能力,成为 Python 自动化/爬虫领域的主流工具。本文串联了浏览器启动、页面操作、元素定位、交互、数据提取、网络拦截等核心 API,并通过实战案例验证了用法。掌握这些 API 后,可高效完成网页自动化测试、数据爬取、表单自动提交等场景的开发。
更多推荐


所有评论(0)