Playwright是微软推出的新一代浏览器自动化库,相比Selenium,它原生支持异步操作、跨浏览器(Chrome/Firefox/Edge/Safari)、自动等待元素加载、内置反爬规避能力,且无需额外下载浏览器驱动,成为爬虫、自动化测试领域的主流选择。
一、Playwright核心优势:为何能替代Selenium?
对比Selenium,Playwright的核心优势一目了然,也是其快速普及的关键:
| 特性 | Playwright | Selenium |
|---|---|---|
| 驱动依赖 | 内置浏览器驱动,无需手动下载 | 需手动匹配浏览器版本下载驱动,易出错 |
| 等待机制 | 自动等待元素加载(无需手动设置显式/隐式等待) | 需手动配置等待,易因元素未加载完成报错 |
| 浏览器支持 | 原生支持Chrome、Firefox、Edge、Safari | 对Safari支持差,需额外配置 |
| 操作模式 | 同步/异步双模式,异步效率更高 | 仅同步为主,异步需额外封装 |
| 反爬规避 | 内置隐藏自动化特征,不易被检测 | 易被识别为自动化工具,需手动配置反爬 |
| 功能丰富度 | 支持截图、录屏、网络拦截、移动端模拟 | 基础功能完善,高级功能需额外插件 |
二、Playwright入门准备:环境搭建
1. 安装Playwright库
# 安装Playwright核心库pipinstallplaywright# 安装浏览器驱动(Chrome/Firefox/webkit/Safari)playwrightinstall说明:playwright install会自动下载对应系统的浏览器二进制文件,无需手动匹配版本,解决了Selenium驱动版本不兼容的痛点。
2. 验证环境
# 同步模式验证fromplaywright.sync_apiimportsync_playwrightwithsync_playwright()asp:# 启动Chrome浏览器(headless=False显示浏览器窗口)browser=p.chromium.launch(headless=False)# 打开新页面page=browser.new_page()# 访问百度首页page.goto("https://www.baidu.com")# 打印页面标题(输出“百度一下,你就知道”则环境正常)print(page.title())# 关闭浏览器browser.close()三、Playwright核心操作:页面与浏览器控制
Playwright分为同步模式(sync_api)和异步模式(async_api),同步模式适合入门,异步模式效率更高(适合批量爬取)。
1. 基础浏览器操作(同步模式)
fromplaywright.sync_apiimportsync_playwright# 上下文管理器自动管理浏览器生命周期withsync_playwright()asp:# 启动浏览器(可选参数:headless=False显示窗口,slow_mo=500放慢操作速度)browser=p.chromium.launch(headless=False,slow_mo=500# 每个操作延迟500ms,便于观察)# 创建浏览器上下文(可设置代理、UA等)context=browser.new_context(user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36")# 打开新页面page=context.new_page()# 核心页面操作page.goto("https://www.baidu.com")# 访问URLpage.reload()# 刷新页面page.go_back()# 后退page.go_forward()# 前进# 获取页面信息print("当前URL:",page.url)print("页面标题:",page.title())print("页面源码:",page.content())# 获取渲染后的完整HTML# 关闭页面和浏览器page.close()browser.close()2. 异步模式(推荐批量操作)
importasynciofromplaywright.async_apiimportasync_playwrightasyncdefmain():asyncwithasync_playwright()asp:# 启动浏览器browser=awaitp.chromium.launch(headless=False)context=awaitbrowser.new_context()page=awaitcontext.new_page()awaitpage.goto("https://www.baidu.com")print(awaitpage.title())awaitbrowser.close()# 执行异步函数asyncio.run(main())3. 窗口与标签页管理
fromplaywright.sync_apiimportsync_playwrightwithsync_playwright()asp:browser=p.chromium.launch(headless=False)context=browser.new_context()# 打开第一个标签页page1=context.new_page()page1.goto("https://www.baidu.com")# 打开第二个标签页page2=context.new_page()page2.goto("https://www.taobao.com")# 获取所有标签页pages=context.pagesprint("标签页数量:",len(pages))# 切换到第一个标签页page1.bring_to_front()# 关闭第二个标签页page2.close()browser.close()四、核心技能:元素定位与用户操作
Playwright支持多种元素定位方式,且自动等待元素可操作(默认等待30秒),无需像Selenium一样手动设置显式等待。
1. 元素定位方式(优先级排序)
| 定位方式 | 代码示例 | 适用场景 |
|---|---|---|
| ID定位 | page.locator("#kw") | 元素有唯一ID |
| Class定位 | page.locator(".s_ipt") | 元素Class属性唯一 |
| 属性定位 | page.locator('[name="wd"]') | 按任意属性定位 |
| XPath定位 | page.locator('//input[@id="kw"]') | 复杂层级定位 |
| CSS选择器 | page.locator("div.s_form > input") | 高效定位,推荐 |
| 文本定位 | page.locator("text=百度一下") | 按元素文本精准匹配 |
| 模糊文本 | page.locator("text=/百度.*/") | 正则匹配文本 |
2. 常用用户操作
(1)输入与清空
fromplaywright.sync_apiimportsync_playwrightwithsync_playwright()asp:browser=p.chromium.launch(headless=False)page=browser.new_page()page.goto("https://www.baidu.com")# 定位搜索框并输入内容search_box=page.locator("#kw")search_box.fill("Playwright教程")# 输入文本search_box.clear()# 清空输入框search_box.fill("Python自动化")# 重新输入browser.close()(2)点击操作
# 定位搜索按钮并点击search_btn=page.locator("#su")search_btn.click()# 模拟回车键(替代点击)search_box.press("Enter")# 双击操作page.locator("text=设置").dblclick()# 右键点击page.locator("#kw").click(button="right")(3)滚动页面
# 滚动到页面底部page.evaluate("window.scrollTo(0, document.body.scrollHeight)")# 滚动到指定元素位置(自动等待元素可见)target=page.locator("#target_id")target.scroll_into_view_if_needed()# 模拟键盘滚动(PageDown)page.keyboard.press("PageDown")(4)处理下拉框
# 定位下拉框并选择选项select=page.locator("#select_id")# 按文本选择select.select_option(label="选项文本")# 按值选择select.select_option(value="option_value")# 按索引选择select.select_option(index=1)# 获取所有选项options=select.locator("option").all_text_contents()print("下拉框选项:",options)(5)处理iframe框架
# 定位iframe并切换(自动等待iframe加载)iframe=page.frame_locator("#iframe_id")# 操作iframe内元素iframe.locator("#inner_btn").click()(6)处理弹窗
# 监听alert弹窗并自动确认page.on("dialog",lambdadialog:dialog.accept())# 触发弹窗操作page.locator("text=触发弹窗").click()# 获取弹窗文本defhandle_dialog(dialog):print("弹窗文本:",dialog.text())dialog.accept()page.on("dialog",handle_dialog)五、进阶技巧:反爬规避与效率优化
1. 无界面模式(后台运行)
fromplaywright.sync_apiimportsync_playwrightwithsync_playwright()asp:# 启动无界面模式(默认headless=True,新版为headless="new")browser=p.chromium.launch(headless="new")page=browser.new_page()page.goto("https://www.baidu.com")print(page.title())browser.close()2. 规避自动化检测(核心优势)
Playwright默认隐藏了大部分自动化特征,无需复杂配置即可规避常规检测:
fromplaywright.sync_apiimportsync_playwrightwithsync_playwright()asp:# 创建上下文时配置反爬参数context=p.chromium.launch_persistent_context("./browser_data",# 持久化浏览器数据(缓存、Cookie)headless=False,args=["--disable-blink-features=AutomationControlled","--no-sandbox",# 禁用沙箱模式"--start-maximized"# 窗口最大化],# 禁用自动化提示ignore_default_args=["--enable-automation"],)page=context.new_page()page.goto("https://example.com")# 验证是否被检测(访问自动化检测页面)page.goto("https://bot.sannysoft.com/")input("按回车关闭浏览器...")context.close()3. 网络拦截与请求控制
Playwright可拦截、修改、阻断网络请求,适合爬取动态数据时过滤无关请求:
fromplaywright.sync_apiimportsync_playwrightdefhandle_request(request):# 阻断图片、视频请求,提升加载速度ifrequest.resource_typein["image","video"]:request.abort()else:request.continue_()withsync_playwright()asp:browser=p.chromium.launch(headless=False)page=browser.new_page()# 注册请求拦截器page.route("**/*",handle_request)page.goto("https://www.taobao.com")browser.close()4. 截图与录屏
fromplaywright.sync_apiimportsync_playwrightwithsync_playwright()asp:browser=p.chromium.launch(headless=False)page=browser.new_page()page.goto("https://www.baidu.com")# 页面全屏截图page.screenshot(path="baidu_page.png",full_page=True)# 元素截图page.locator("#kw").screenshot(path="search_box.png")# 录屏(需安装ffmpeg,playwright install ffmpeg)context=browser.new_context(record_video_dir="./videos/")page2=context.new_page()page2.goto("https://www.taobao.com")page2.click("text=首页")context.close()# 关闭上下文时自动保存视频browser.close()六、实战案例:爬取JS动态加载的商品数据
以某电商平台商品列表为例(JS动态加载),爬取商品名称、价格、销量,对比Selenium更简洁高效:
fromplaywright.sync_apiimportsync_playwrightimporttimedefcrawl_goods():withsync_playwright()asp:# 启动浏览器browser=p.chromium.launch(headless=False,slow_mo=200)page=browser.new_page()# 访问商品列表页page.goto("https://xxx.com/goods-list")# 滚动加载更多商品(模拟翻页)for_inrange(3):# 滚动到页面底部page.evaluate("window.scrollTo(0, document.body.scrollHeight)")# Playwright自动等待,无需手动sleep(此处为模拟用户操作间隔)time.sleep(1)# 定位所有商品元素并提取信息goods_list=page.locator(".goods-item").all()forgoodsingoods_list:# 提取商品名称(自动等待元素可见)name=goods.locator(".goods-name").inner_text()# 提取价格price=goods.locator(".goods-price").inner_text()# 提取销量sales=goods.locator(".goods-sales").inner_text()print(f"商品名称:{name},价格:{price},销量:{sales}")browser.close()if__name__=="__main__":crawl_goods()七、Playwright vs Selenium:迁移指南
若已有Selenium代码,可按以下规则快速迁移到Playwright:
| Selenium操作 | Playwright对应操作 |
|---|---|
driver.get(url) | page.goto(url) |
driver.find_element(By.ID, "kw") | page.locator("#kw") |
element.send_keys(text) | locator.fill(text) |
element.click() | locator.click() |
driver.page_source | page.content() |
WebDriverWait(driver, 10).until(EC.visibility_of_element_located) | locator.wait_for()(Playwright自动等待,无需手动调用) |
driver.switch_to.frame(iframe) | page.frame_locator(iframe_locator) |
八、常见问题与避坑指南
- 元素定位失败:
- Playwright的
locator默认等待元素可操作,若仍失败,检查是否在iframe内(用frame_locator); - 避免使用绝对XPath,优先用CSS选择器或文本定位。
- Playwright的
- 浏览器启动失败:
- 无权限时添加
args=["--no-sandbox"]; - Windows系统需确保Playwright下载的浏览器路径无中文。
- 无权限时添加
- 反爬检测:
- 启用持久化上下文(
launch_persistent_context),模拟真实用户浏览器数据; - 避免短时间高频操作,添加随机间隔。
- 启用持久化上下文(
- 异步模式报错:
- 确保异步函数嵌套正确,避免同步/异步混用;
- Windows系统需安装
asyncio最新版:pip install --upgrade asyncio。