使用Puppeteer爬取Unieuro网站无法获取指定元素列表的问题求助
问题原因及修复方案
1. 选择器超时的核心原因
你点击搜索按钮后会触发页面跳转,旧页面已经被销毁,你直接在原上下文等待新页面的元素必然触发超时,强制等待3秒属于不可靠的临时方案,正确写法是等待页面导航完成:
// 把原来的点击搜索逻辑替换成这个,同时等待导航和点击操作完成 await Promise.all([ page.waitForNavigation(), page.click(".icon-search") ]) // 接下来就可以正常等待目标元素,不需要强制超时 await page.waitForSelector('.product-tile__title', {timeout: 10000})
2. 提取内容代码错误的修复
你写的$$eval回调逻辑有两处错误:
- 遍历得到的文本数组没有被返回,你直接返回了原始DOM元素数组,而Puppeteer的evaluate类接口无法序列化DOM元素,所以只会返回空对象
- 不需要再额外查询子元素a,可以直接把选择器定位到a标签
正确的写法如下:
const productNames = await page.$$eval(".product-tile__title a", els => { return els.map(el => el.textContent.trim()) }) // 此时productNames就是所有商品标题的字符串数组
如果需要同时提取其他商品信息,也可以定位到父级元素统一处理:
const products = await page.$$eval(".product-tile", els => { return els.map(el => { return { title: el.querySelector(".product-tile__title a")?.textContent.trim() || '', // 还可以加价格、链接等其他字段 } }) })
3. 更简单的Node.js爬虫方案说明
如果目标页面是静态渲染的,不需要交互操作,优先用axios + cheerio的方案,开发成本和运行效率都远高于Puppeteer:
- 用
axios发HTTP请求拿页面HTML内容 - 用
cheerio加载HTML,之后可以用和jQuery完全一致的语法提取元素内容,不需要处理浏览器上下文、页面导航、元素加载等逻辑
你觉得现有爬虫库复杂度高,主要是两个原因:
- 现在大量站点采用前端动态渲染、反爬策略,普通的请求式爬虫拿不到完整内容,必须用Puppeteer这类无头浏览器方案模拟真实用户操作,本身这类方案的逻辑就更复杂
- 刚接触相关API不熟悉常见坑点,比如不知道点击后要等导航、evaluate只能返回可序列化数据等,熟悉之后会大幅降低踩坑概率
内容的提问来源于stack exchange,提问作者M1S0
相关产品推荐
相关产品推荐

