使用Playwright的locator方法进行Node.js爬虫速度过慢的问题排查
问题分析与解决方案
你的问题不是Playwright的locator方法性能差,而是使用方式不对。
为什么300次locator调用会慢?
Playwright的locator是基于真实浏览器的自动化操作,每次调用innerText()都会触发:
- 浏览器端查找元素
- 等待元素处于可交互/可见状态(Playwright默认的自动等待机制)
- 把结果从浏览器进程传输到Node.js进程
300次这样的跨进程往返操作,加上每次的等待检查,累计起来就会有明显的耗时。而Cheerio是直接在Node.js内存里解析静态HTML,所有DOM操作都是本地同步的,自然快很多。
正确的优化方式
既然目标是提取一个父div下50个子div的信息,完全不需要调用300次locator,应该批量提取数据,减少跨进程通信的次数:
方案1:批量定位子元素并获取数据
// 先定位到包含所有子项的父容器 const itemList = page.locator('div.你的父容器选择器 > div.iva-item-sellerInfo-_q_Uw'); // 一次性获取所有子项的目标文本 const allFinishedAds = await itemList.locator('span.iva-item-text-Ge6dR').allInnerTexts();
方案2:在浏览器上下文一次性提取所有数据
如果需要提取多个字段,用page.evaluate()直接在浏览器端处理DOM,只返回最终结果数组,彻底减少跨进程通信:
const allItemData = await page.evaluate(() => { // 一次性获取所有子div元素 const items = Array.from(document.querySelectorAll('div.你的父容器选择器 > div.iva-item-sellerInfo-_q_Uw')); // 遍历提取每个元素的所需信息 return items.map(item => { return { finishedAd: item.querySelector('span.iva-item-text-Ge6dR')?.textContent.trim() || '', // 可添加其他需要提取的字段,比如标题、价格等 }; }); });
总结
Playwright的优势在于处理动态渲染页面(如SPA、需要交互加载的内容),但提取静态列表数据时,通过批量操作或一次性在浏览器端提取完整数据,就能大幅降低耗时,性能可接近Cheerio的水平,核心是避免不必要的跨进程往返开销。
内容的提问来源于stack exchange,提问作者Gayrat Vlasov
相关产品推荐
相关产品推荐

