Playwright 爬虫教程 (2024 最新版)
还在为 Selenium 的驱动版本匹配头疼?受够了 Puppeteer 只能绑在 Chromium 上的限制?如果你需要抓取动态渲染页面,微软开源的 Playwright 绝对值得一试。经过四年迭代,它已经成为自动化工具里的顶流,做动态爬虫简直爽快得不像话。
1. 为什么选 Playwright 做爬虫?
和其他工具相比,Playwright 几乎精准解决了爬虫工程师的核心痛点:
- 全引擎覆盖:Chromium、Firefox、WebKit(Safari 内核)全部支持,再也不用为了测试反爬策略换浏览器改代码。
- 全平台统一:Windows、macOS、Linux 的驱动安装是一条命令搞定,告别
chromedriver.exe 下载失败的糟心体验。
- 智能自动等待:不用写满屏的
time.sleep() 或复杂的等待条件。Playwright 会等到元素可交互时才执行操作,大幅降低脚本脆弱性。
- 反爬友好:内置设备指纹模拟、地理位置伪装、网络拦截等实用功能,应对基础反爬得心应手。
- 性能拉满:比 Selenium 快,功能比 Puppeteer 更全,异步 API 更能胜任高并发采集。
2. 快速安装配置
环境要求
Python 3.8 及以上,主流操作系统全支持。
国内加速安装方案
网络通畅可以直接走官方源,但国内用户大概率会卡在依赖下载环节,推荐使用镜像加速:
# 安装 Playwright Python 库(清华镜像)
pip install playwright -i https://pypi.tuna.tsinghua.edu.cn/simple
# 下载三大浏览器引擎(约 200~300MB,使用 npmmirror 加速)
PLAYWRIGHT_DOWNLOAD_HOST=https://npmmirror.com/mirrors/playwright playwright install
网络环境较好的同学可以直接用官方源:
pip install playwright
playwright install
3. 基础入门:同步 VS 异步
Playwright 提供了同步和异步两种 API 风格。日常小脚本推荐用同步模式,逻辑直观;需要同时跑几十个页面的场景,直接换成异步模式,效率明显更高。
同步模式:几行代码打开百度
下面是最简单的入门示例——打开百度首页、打印标题、截图保存:
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
# headless=False 显示浏览器窗口,True 为后台运行
browser = p.chromium.launch(headless=False)
page = browser.new_page()
page.goto("https://www.baidu.com")
print(f"页面标题: {page.title()}")
page.screenshot(path="baidu_home.png")
with 语句会自动管理浏览器生命周期,不用手动 close(),代码干净又安全。
异步模式:更适合批量操作
如果你要同时采集多个页面,异步模式能帮你榨干网络和 CPU:
import asyncio
from playwright.async_api import async_playwright
async def open_baidu():
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(open_baidu())
4. 懒人神器:代码生成工具
写爬虫最烦人的就是元素定位?Playwright 自带的 codegen 录制器让你告别手动找选择器。你在浏览器里怎么操作,它就自动生成对应的 Python 代码。
比如录制登录 B 站的操作,只需一行命令:
playwright codegen --target python -o bilibili_login.py -b firefox https://www.bilibili.com
执行后会同时打开 Firefox 浏览器和代码生成窗口,你输入账号、点击登录,右侧脚本会实时更新,稍作修改就能直接使用。
5. 核心功能:爬动态渲染页面的必备操作
元素定位
Playwright 支持多种定位策略,新手可以从最直观的方式开始:
# 文本选择(适合反爬较弱的页面)
page.click("text=登录")
# CSS 选择器(和 BeautifulSoup 一样,学习成本为零)
page.fill("#login-username", "your_username")
page.fill(".login-password", "your_password")
# 组合选择器(精准定位包含特定文本的元素)
page.click("article:has-text('Playwright爬虫教程')")
等待机制(自动等待不够用时加料)
虽然 Playwright 自带自动等待,但遇到无限滚动、异步加载等场景,你可能需要手动补充:
# 等待某个元素出现在 DOM 且可见(最常用)
page.wait_for_selector(".dynamic-data-item", timeout=30000)
# 等待网络空闲(所有请求完成)
page.wait_for_load_state("networkidle")
# 极少情况下的强制暂停(能不用就不用)
page.wait_for_timeout(2000)
网络拦截:禁用图片与广告,提速显著
动态页面往往夹杂大量无用的图片和广告请求,用 route 拦截可以大幅加速采集:
import json
# 拦截所有图片请求
page.route("**/*.{png,jpg,jpeg,gif,webp}", lambda route: route.abort())
# 拦截广告接口
page.route("**/ad/**", lambda route: route.abort())
# 甚至可以直接修改接口响应(用于测试或绕过部分检查)
page.route("**/api/user-info", lambda route: route.fulfill(
status=200,
content_type="application/json",
body=json.dumps({"name": "test_user", "level": 10})
))
6. 实用反爬技巧(基础版)
模拟移动端设备
很多网站对移动端的反爬措施相对宽松,Playwright 内置了丰富的设备配置,一键伪装:
with sync_playwright() as p:
iphone_15 = p.devices["iPhone 15 Pro"]
# 搭配 WebKit(Safari 内核)更逼真
browser = p.webkit.launch(headless=False)
context = browser.new_context(**iphone_15)
page = context.new_page()
page.goto("https://www.taobao.com")
page.screenshot(path="taobao_mobile.png")
设置地理位置
除了 IP 代理,你还可以通过浏览器上下文直接模拟地理位置,配合一些需要区域判断的站点:
context = browser.new_context(
**iphone_15,
# 北京天安门坐标
geolocation={"latitude": 39.913904, "longitude": 116.39014},
permissions=["geolocation"]
)
7. 常见问题与解决思路
Q1: 元素点击失败?
- 检查元素是否被弹窗、广告遮挡
- 尝试强制点击:
page.click(selector, force=True)
- 先滚动到元素可见区域:
page.scroll_into_view_if_needed(selector)
Q2: 页面加载超时?
- 延长超时时间:
page.goto(url, timeout=60000)
- 拦截不必要的资源(如图片、广告),减少等待
- 检查目标网站是否需要配置代理
Q3: 如何应对验证码?
- 复杂验证码(滑块、点选、拼图)建议对接第三方识别服务
- 使用持久化浏览器上下文保存登录状态和 cookies,减少重复登录,降低触发验证码的几率
8. 资源推荐
遇到问题别着急,官方文档内容详尽,中文资料也十分丰富:
Playwright 不仅能做动态爬虫,在自动化测试领域同样是一把好手。希望这篇教程能帮你快速上手,后续还有更多高级玩法等你探索!