直接结论:在新建的动态网页采集项目中,如果目标网站大量使用 JavaScript 渲染、异步接口、弹窗或复杂交互,Playwright 通常比 Selenium 更容易获得稳定且可维护的采集链路;如果企业已经拥有成熟的 Selenium 测试平台、浏览器兼容资产和运维体系,继续使用 Selenium 可能更经济。真正影响选择的不是单次抓取速度,而是等待机制、网络请求控制、并发模型、故障定位和长期维护成本。

Selenium 与 Playwright 网页采集对比:电商监测项目的落地、踩坑与选型经验

下面以一个经过匿名化处理的电商商品监测项目为例,说明 Selenium 与 Playwright 网页采集对比在真实业务中的落地过程。文中的耗时和成功率用于展示评估方法,不代表所有网站都能得到相同结果。采集前应确认目标网站的服务条款、robots 规则、数据授权和适用法律,不应绕过登录权限、验证码或访问控制。

案例背景:电商商品价格与库存监测

业务目标

项目需要每天采集约 3 万个公开商品页面,字段包括商品名称、当前价格、划线价、促销标签、库存状态、规格和更新时间。页面采用前端框架渲染,首屏 HTML 中没有完整商品数据,切换规格后还会发起新的接口请求。

团队最初已有 Selenium 使用经验,因此先用 Selenium 编写原型;随着任务量增加,项目出现超时、元素失效和浏览器进程残留等问题,随后选取同一批页面迁移到 Playwright,对两套方案进行了两周的并行验证。

统一评估口径

为了避免只凭开发体验判断工具,团队固定了浏览器版本、机器配置、代理策略、请求频率和样本集合,并重点记录以下指标:

  • 有效页面成功率:关键字段完整且通过业务校验的页面比例。
  • 单页处理时间:从创建页面到得到结构化结果的总耗时。
  • 资源消耗:相同并发量下的 CPU、内存和浏览器进程数量。
  • 恢复能力:超时、页面崩溃或网络异常后能否自动回收并重试。
  • 维护成本:定位选择器失效、接口变化和弹窗干扰所需的时间。

第一阶段:使用 Selenium 完成采集原型

落地过程

Selenium 版本采用 Python、Chrome 和显式等待。任务从队列中读取商品 URL,每个 Worker 维护一个浏览器实例,依次打开页面、关闭活动弹窗、等待价格区域出现,再遍历规格按钮并读取页面文本。

原型在少量样本上可以工作,但扩大到数千个页面后,稳定性开始下降。主要原因不是 Selenium 无法采集,而是页面状态比原型预期更复杂:价格容器先出现骨架屏,随后才填入数据;点击规格后旧节点会被前端重新创建;部分资源加载缓慢导致页面加载事件迟迟不结束。

Selenium 版本遇到的问题

  1. 等待条件不够精确:仅等待元素出现时,抓到的可能是空容器。后来将条件改为价格文本非空、加载标记消失且规格处于选中状态。
  2. StaleElementReferenceException:切换规格后 DOM 节点被替换,之前保存的元素引用失效。解决方式是每次交互后重新定位元素,不长期缓存 WebElement。
  3. 隐式等待与显式等待叠加:两种等待混用会放大实际超时时间,使故障任务长时间占用 Worker。项目最终关闭隐式等待,只保留针对业务状态的显式等待。
  4. 浏览器进程残留:异常分支没有可靠执行 quit,持续运行后出现 Chrome 子进程堆积。团队增加 finally 回收、Worker 生命周期上限和进程监控。
  5. 网络层信息获取繁琐:部分字段实际来自 JSON 接口,但原方案主要依赖 DOM。接入性能日志或 DevTools 能力后可以获取请求,不过实现和调试成本高于预期。

阶段结果

在固定样本中,经过多轮修正后的 Selenium 方案能够满足基础采集需求,但页面结构稍有变化就容易出现字段为空。匿名化测试结果约为 94% 至 96% 的一次成功率,中位单页耗时约 6.8 秒。这个结果并不说明 Selenium 性能一定较差,而是说明该项目依赖异步状态和接口响应,单纯从 DOM 读取数据需要维护更多等待逻辑。

第二阶段:迁移 Playwright 并重构采集链路

迁移思路

迁移时没有逐行翻译 Selenium 脚本,而是把流程拆成导航、状态确认、数据提取、业务校验、重试和资源回收六个阶段。Playwright 负责浏览器自动化和网络监听,任务队列负责限速与调度,结构化结果进入校验层后再写入数据库。

浏览器按 Worker 复用,每个任务创建独立 BrowserContext。这样既减少了反复启动浏览器的开销,也能隔离 Cookie、缓存和页面状态。对于无需展示的图片、字体和媒体资源,通过路由规则进行拦截,但保留脚本、样式和数据接口,避免页面功能被破坏。

从 DOM 采集转向接口优先

团队通过 Playwright 的 response 事件定位到商品详情接口。导航页面后,脚本等待目标响应并解析 JSON,页面 DOM 仅用于补充接口中没有的促销文案和展示状态。

这种方式带来两个直接收益:第一,减少了对 CSS 类名和嵌套层级的依赖;第二,接口响应通常已经包含结构化字段,不需要从格式化价格文本中再次解析数值。但接口优先并不等于绕过权限,只有浏览器正常访问且业务允许使用的公开响应才应被处理。

利用 Locator 和自动等待

Playwright 的 Locator 会在操作时重新解析目标,并对可见、稳定、可操作等条件执行自动等待,因此前端重新渲染节点时,通常不需要手动保存和刷新元素引用。项目仍然保留业务级等待,例如等待价格接口返回、库存字段通过校验,而不是把自动等待当成所有问题的解决方案。

阶段结果

在同一批匿名化样本和相同访问频率下,Playwright 版本的一次成功率约为 98%,中位单页耗时降至约 4.1 秒。性能改善主要来自拦截非必要资源、复用浏览器、使用独立 Context,以及直接解析结构化响应,而不是工具名称本身。迁移后,选择器相关故障减少,失败任务也更容易通过 Trace、截图和网络记录复现。

Selenium 与 Playwright 的实际表现对比

比较维度SeleniumPlaywright案例中的影响
等待机制常需明确编写显式等待Locator 操作内置自动等待Playwright 减少了空节点和时序问题,但业务状态仍需单独校验
动态 DOM保存元素引用后可能失效Locator 会重新定位规格切换后的维护代码更少
网络监听可借助 DevTools、日志或扩展能力实现请求、响应和路由拦截是一等能力更容易采用接口优先、DOM 补充的采集方式
上下文隔离通常通过多实例或配置管理会话BrowserContext 使用方便且开销较低浏览器复用时更容易隔离任务状态
调试能力生态成熟,可结合截图、日志和 GridTrace Viewer 可统一查看操作、网络和页面快照异步故障定位时间明显缩短
浏览器覆盖支持范围广,适合既有 WebDriver 体系重点支持 Chromium、Firefox 和 WebKit本项目只需要主流现代浏览器,Playwright 足够
团队迁移成本已有经验时成本较低需要学习异步模型、Locator 和 Context首周开发速度下降,稳定后维护效率提升

项目中的主要踩坑与解决方法

坑一:把自动等待理解成无需等待

Playwright 会等待元素具备交互条件,但不会自动理解“价格接口已经完成第二次刷新”或“库存值已经对应当前规格”。解决方法是为关键业务状态设置明确断言,例如规格 ID、接口参数和返回字段必须一致。

项目中的主要踩坑与解决方法

坑二:使用 networkidle 作为所有页面的完成条件

部分网站存在轮询、埋点和长连接,请求不会真正归零,networkidle 可能导致不必要的超时。实际项目改为等待目标接口响应,或等待特定数据节点达到可验证状态。

坑三:为了提速拦截过多资源

阻止所有样式、图片或第三方脚本后,页面可能改变响应式布局,也可能导致懒加载逻辑不执行。正确做法是逐类验证:先阻止字体和视频,再根据页面行为决定是否阻止图片;对影响业务状态的脚本和接口保持放行。

坑四:无限提高并发

浏览器自动化属于资源密集型任务,提高并发会同时增加 CPU、内存、网络连接和目标站点压力。项目根据单 Worker 内存上限和错误率动态调整并发,并为域名设置访问间隔。出现 429 或 503 时执行退避,而不是立即重复请求。

坑五:只用 HTTP 状态码判断成功

页面返回 200 不代表数据有效,错误页、风控提示和空壳页面也可能返回 200。采集结果需要经过字段完整性、价格范围、商品 ID 一致性和页面类型校验,失败原因也应区分为网络错误、页面变化、权限限制和业务数据缺失。

坑六:重试时复用污染状态

第一次失败可能留下弹窗、异常 Cookie 或未完成请求。如果重试继续使用同一页面,错误会被放大。案例中一般关闭失败页面并创建新的 Context;只有明确属于短暂接口超时时,才在同一上下文中进行有限次数重试。

不同场景下如何选型

优先选择 Playwright 的场景

  • 新项目以现代动态网页为主,需要监听或拦截请求。
  • 采集流程包含弹窗、标签页、文件下载、规格切换等复杂交互。
  • 需要使用 Trace 快速复现间歇性错误。
  • 希望在一个浏览器进程中通过多个 Context 隔离任务。
  • 团队使用 Node.js、Python、Java 或 .NET,且能接受相应版本升级节奏。

继续使用 Selenium 更合适的场景

  • 企业已有稳定的 Selenium Grid、监控体系、驱动管理和大量公共组件。
  • 项目不仅用于采集,还要复用既有的跨浏览器自动化测试资产。
  • 目标环境依赖 Selenium 已覆盖的浏览器、设备或供应商平台。
  • 采集页面结构简单,当前脚本稳定,迁移收益不足以覆盖重写与验证成本。

商业项目的决策方法

选型前应制作一组代表性样本,覆盖登录前后页面、慢接口、多规格、弹窗、分页、异常页面和高峰时段。用两套最小实现运行至少数天,再比较有效数据成本,而不是只比较每秒打开多少页面。

有效数据成本可以综合计算机器资源、代理流量、失败重试、人工维护和数据延迟。对多数企业而言,一次成功率从 95% 提升到 98% 的价值,可能高于单页节省一秒;但如果迁移需要重建成熟平台,Selenium 的总体拥有成本也可能更低。

可复用的实施流程

  1. 确认边界:核查授权、服务条款、字段用途、保存周期和个人信息处理要求。
  2. 建立样本:覆盖不同页面模板、地区、登录状态和异常场景。
  3. 优先分析数据来源:判断字段来自初始 HTML、异步接口还是用户交互后的响应。
  4. 设计分层:把浏览器控制、提取规则、业务校验、存储和调度分开。
  5. 设置可观测性:记录任务 ID、页面 URL、响应状态、失败分类、截图或 Trace。
  6. 控制并发与重试:设置域名级限速、指数退避和最大重试次数。
  7. 小流量灰度:先运行代表性任务,确认字段质量和资源消耗后再逐步扩容。
  8. 持续回归:保存脱敏样本与字段断言,在页面改版后快速发现规则失效。

常见问题

Selenium 和 Playwright 哪个更适合动态网页采集?

对于大量使用异步请求、前端重渲染和复杂交互的现代网页,Playwright 通常更容易实现稳定采集。对于已有 Selenium Grid、公共组件和运维体系的团队,Selenium 仍可能是总体成本更低的选择。

Playwright 一定比 Selenium 快吗?

不一定。速度取决于浏览器复用方式、资源加载、等待条件、并发配置和数据提取路径。案例中的提速主要来自接口解析、资源拦截和 Context 复用,不能简单归因于工具本身。

网页采集应该读取 DOM 还是直接读取接口响应?

如果浏览器正常访问时返回了结构化公开数据,并且使用方式符合授权和服务条款,接口响应通常更稳定;展示文案和最终渲染状态仍可由 DOM 补充。两者结合往往比完全依赖 CSS 选择器更可靠。

从 Selenium 迁移到 Playwright 时最容易忽略什么?

最容易忽略的是直接逐行翻译脚本。迁移时应重新设计等待条件、会话隔离、网络监听、错误分类和资源回收,同时避免把 Playwright 的自动等待误解为无需业务校验。

如何评估采集工具的商业成本?

应综合有效数据成功率、单页处理时间、机器与流量成本、失败重试、人工维护、故障恢复和数据延迟。仅比较启动速度或单次抓取耗时,无法反映长期总体拥有成本。

遇到验证码或访问限制应该怎么处理?

应降低频率并检查是否具备访问授权,不应尝试绕过验证码、登录权限或技术访问控制。商业项目应优先使用官方 API、数据合作或明确授权的数据渠道。

总结

通过匿名化电商监测案例可以看到,Playwright 在动态 DOM、网络监听、任务隔离和故障调试方面更适合新建的现代网页采集项目;Selenium 则适合复用成熟的 WebDriver 平台与企业存量资产。选型时应使用统一样本评估有效成功率、资源成本和维护成本,并将合规检查、业务校验、限速重试、进程回收和可观测性纳入完整实施方案。