Playwright Python 教程:从安装到动态网页自动化实战
面向爬虫和 Web 自动化学习者的 Playwright Python 入门教程,覆盖安装、同步与异步模式、元素定位、等待策略、上下文管理、网络拦截、截图调试和实践建议。
Playwright Python 适合解决什么问题
Playwright Python 教程最适合从一个具体目标开始理解:当网页内容依赖 JavaScript 渲染、按钮点击、登录状态、滚动加载或接口异步返回时,传统的 requests 往往只能拿到不完整的 HTML,而 Playwright 可以像真实浏览器一样打开页面、执行脚本、点击元素、等待请求完成,再把页面状态交给你处理。
在爬虫、自动化测试和日常 Web 自动化任务里,Playwright 的核心价值主要有三点:
- 支持 Chromium、Firefox、WebKit 多浏览器引擎,便于验证不同浏览器表现。
- 自带智能等待机制,能减少“元素还没加载就开始点击”的不稳定问题。
- 提供定位器、上下文、网络拦截、设备模拟、截图和 PDF 等完整浏览器自动化能力。
如果你正在处理动态页面、登录后页面、无限滚动列表、前端渲染数据、按钮触发加载等场景,Playwright 通常比单纯解析网页源代码更可靠。
安装 Playwright Python
Python 项目中可以用 uv 安装 Playwright:
uv add playwright
国内网络环境下,浏览器内核下载可能较慢,可以先设置下载源:
# Windows cmd
set PLAYWRIGHT_DOWNLOAD_HOST=https://registry.npmmirror.com/-/binary/playwright
# macOS / Linux
export PLAYWRIGHT_DOWNLOAD_HOST=https://registry.npmmirror.com/-/binary/playwright
然后安装 Chromium 浏览器内核:
playwright install chromium
如果浏览器内核安装失败,常见原因是镜像源没有及时同步对应版本。可以尝试降低 Playwright 版本,例如:
uv add playwright==1.50.0
playwright install chromium
同步模式和异步模式怎么选
Playwright Python 同时支持同步 API 和异步 API。初学、写小脚本、调试单个页面时,同步模式更直观;需要并发处理多个页面、接入异步任务队列或和异步 Web 服务集成时,异步模式更合适。
同步模式示例
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://example.com")
title = page.title()
print(f"页面标题: {title}")
browser.close()
异步模式示例
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()
await page.goto("https://example.com")
title = await page.title()
print(f"页面标题: {title}")
await browser.close()
asyncio.run(main())
做爬虫自动化时,如果页面数量较多,不建议简单地无限并发打开浏览器页面。更稳妥的做法是控制并发数量、设置超时、复用浏览器上下文,并在异常时释放页面资源。
元素定位:优先使用稳定语义
Playwright 的定位能力很强,但定位器写得是否稳定,会直接影响脚本能否长期运行。常见定位方式包括 CSS 选择器、XPath、文本匹配、角色定位和标签定位。
# CSS 选择器
page.locator("#my-id")
page.locator(".my-class")
page.locator("div[attr='value']")
# XPath
page.locator("xpath=//button")
# 文本匹配
page.locator("text=按钮文字")
page.locator(".movie-title:has-text('肖申克')")
# 角色定位,推荐优先考虑
page.get_by_role("button", name="提交")
# 标签定位
page.get_by_label("Password")
在真实项目里,推荐优先使用 get_by_role()、get_by_label() 这类语义化定位器。它们更接近用户看到和操作页面的方式,也更容易发现页面可访问性问题。只有当页面结构缺少语义信息时,再考虑 CSS 选择器或 XPath。
表单、点击和下拉选择
Playwright 可以完成常见用户交互,例如输入、点击、选择下拉框、勾选复选框:
# 输入文本
page.fill("input[name='username']", "张三")
# 点击提交按钮
page.click("button[type='submit']")
# 选择下拉选项
page.select_option("select[name='country']", "China")
# 勾选复选框
page.check("input[type='checkbox']")
如果脚本偶发失败,不要第一时间增加固定 sleep。更好的排查顺序是确认定位器是否稳定、元素是否可见、是否被遮挡、点击后是否触发了导航或接口请求。
等待策略:少用固定 sleep,多等确定条件
Playwright 有智能等待机制,但复杂动态页面仍然需要明确等待条件。常见等待方式包括等待元素出现、等待元素可见、等待请求返回和等待导航完成。
# 等待元素出现
page.wait_for_selector("#dynamic-content")
# 等待按钮可见
page.wait_for_selector("button#submit", state="visible")
# 等待接口响应
with page.expect_response("**/api/data") as response_info:
page.click("button#load-data")
response = response_info.value
# 等待导航完成
with page.expect_navigation():
page.click("a#next-page")
动态页面加载不完整时,可以根据页面特征选择不同加载状态:
page.goto(url, wait_until="networkidle")
page.wait_for_load_state("domcontentloaded")
page.wait_for_load_state("load")
networkidle 适合等待页面网络请求基本安静,但不是所有页面都适用。有些站点会持续轮询接口,此时一直等待网络空闲反而会拖慢脚本。更可靠的方式是等待你真正需要的数据元素、列表项或目标接口。
浏览器上下文:隔离登录态和运行环境
浏览器上下文可以理解为一个独立浏览器环境。不同上下文之间 Cookie、localStorage、语言、视口、User-Agent 可以隔离,适合用来模拟不同用户或不同设备。
context = browser.new_context(
viewport={"width": 1920, "height": 1080},
user_agent="Custom User Agent",
locale="zh-CN"
)
page1 = context.new_page()
page2 = context.new_page()
在爬虫任务中,上下文复用通常比频繁启动浏览器更高效。一个常见实践是:浏览器进程保持运行,按任务创建上下文或页面,任务结束后关闭页面和上下文,避免资源泄漏。
网络拦截和响应模拟
Playwright 不只能操作页面,还能拦截请求、阻止无关资源加载,或模拟接口返回。这对调试前端页面、减少无关网络开销、稳定测试数据很有帮助。
def handle_request(route, request):
if "analytics.js" in request.url:
route.abort()
else:
route.continue_()
page.route("**/*", handle_request)
模拟接口响应:
page.route("**/api/user", lambda route: route.fulfill(
status=200,
content_type="application/json",
body='{"id": 1, "name": "Mocked User"}'
))
在爬虫场景中,请求拦截可以用来屏蔽图片、统计脚本、广告脚本等非核心资源,但要谨慎处理。如果页面业务逻辑依赖某些脚本,盲目拦截可能导致页面状态异常。
设备模拟、截图和 PDF
Playwright 内置多种设备配置,可以快速模拟手机和平板页面:
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch()
iphone_11 = p.devices["iPhone 11 Pro"]
context = browser.new_context(**iphone_11)
常用设备包括:
iPhone 11 ProPixel 5Galaxy S8iPad Mini
截图和 PDF 也很适合用于调试、留存证据或生成页面快照:
page.screenshot(path="screenshot.png")
page.locator("#element").screenshot(path="element.png")
# 仅 Chromium 支持
page.pdf(path="page.pdf")
如果你在做自动化采集,截图可以帮助定位失败现场。相比只记录异常文本,保留页面截图往往更容易发现弹窗、验证码、登录过期、布局变化等问题。
调试和事件监听
Playwright 支持监听控制台消息、页面错误和弹窗:
page.on("console", lambda msg: print(msg.text))
page.on("pageerror", lambda exc: print(f"页面错误: {exc}"))
page.on("dialog", lambda dialog: dialog.accept())
调试页面交互时,可以打开有头模式:
browser = p.chromium.launch(headless=False)
也可以在关键位置暂停:
page.pause()
调试时建议先把脚本跑稳,再考虑无头模式、并发和性能优化。过早追求速度,通常会把问题隐藏到更难排查的地方。
反检测配置要谨慎使用
一些场景会看到类似配置:
browser = p.chromium.launch(
headless=False,
args=[
"--disable-blink-features=AutomationControlled",
"--disable-dev-shm-usage"
]
)
这类参数可能降低部分自动化特征,但不应被理解为可以绕过网站规则。实际项目中更重要的是控制访问频率、遵守 robots、尊重登录授权和数据使用边界。对于需要登录、付费、个人信息或平台风控的页面,应先确认授权范围,再设计自动化流程。
Playwright 爬虫实践建议
把 Playwright 用在爬虫任务时,可以按下面的顺序设计脚本:
- 先确认页面数据是否必须经过浏览器渲染。如果接口能直接合法访问,优先使用接口或轻量 HTTP 客户端。
- 如果必须操作页面,先用有头模式跑通完整流程,包括打开页面、定位元素、触发加载、读取结果。
- 为关键步骤设置明确等待条件,例如目标元素出现、列表数量变化、接口返回完成。
- 复用浏览器实例,合理创建上下文和页面,避免每条数据都重启浏览器。
- 给页面跳转、接口等待、任务执行设置超时,失败时记录 URL、截图和错误信息。
- 控制并发和访问频率,避免对目标站点造成异常压力。
一个稳定的 Playwright 脚本,通常不是靠大量 sleep 堆出来的,而是靠稳定定位器、明确等待条件、可恢复的异常处理和可观测的日志。
常见问题
Playwright 和 Selenium 有什么区别
两者都能做浏览器自动化。Playwright 的现代浏览器支持、自动等待、上下文隔离和网络控制能力更完整,写动态页面自动化脚本时通常更顺手。Selenium 生态更久,存量资料和企业测试体系也更多。
Playwright 能替代 requests 吗
不能简单替代。requests 更轻量,适合直接请求接口或静态页面;Playwright 更重,但能处理 JavaScript 渲染和复杂交互。实际爬虫项目里,两者经常配合使用。
为什么页面明明打开了,元素还是定位不到
常见原因包括元素在 iframe 中、内容还没加载完成、定位器不唯一、元素被弹窗遮挡、页面语言或设备布局不同。排查时可以先截图,再检查页面结构和网络请求。
什么时候不适合用 Playwright
如果数据来自稳定接口、页面不需要 JavaScript 渲染,或者任务量非常大且对性能要求极高,直接 HTTP 请求通常更合适。Playwright 更适合少量复杂页面、强交互页面和需要真实浏览器环境的任务。
总结
学习 Playwright Python,可以先掌握安装、同步和异步模式、元素定位、表单交互、等待策略、上下文管理、网络拦截、设备模拟、截图调试这几块能力。真正写项目时,重点不是把 API 背完,而是能判断:什么时候该用浏览器自动化,等待什么条件才稳定,如何记录失败现场,以及如何在合规边界内控制访问频率。
对爬虫学习者来说,Playwright 是处理动态网页的重要工具,但它不是万能钥匙。把它和 HTTP 基础、DOM 结构、CSS 选择器、XPath、接口分析一起学习,才能更稳地解决真实网页采集和自动化问题。
Practice