You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Puppeteer获取指定类名元素数组并遍历子元素提取数据

解决方法

你用page.$$获取到的是ElementHandle数组,本身支持查询子元素,问题出在后续的调用方式,以下是可直接运行的完整实现方案:

核心逻辑说明

ElementHandle实例自身携带$和$$方法,调用这两个方法即可从当前元素的子节点中匹配选择器,而非从整个文档根节点匹配。所有DOM属性的读取都需要通过page.evaluate执行,不可直接在Node侧读取代理对象的属性。

完整代码示例

const puppeteer = require('puppeteer');

(async () => {
  // 启动浏览器
  const browser = await puppeteer.launch({ headless: 'new' });
  const page = await browser.newPage();
  // 跳转目标页面,等待网络空闲
  await page.goto('https://altadefinizione.sale/?s=matrix', { waitUntil: 'networkidle2' });

  // 你原本获取卡片数组的代码是正确的
  const cardHandles = await page.$$('.col-lg-3.col-md-4.col-xs-4.mb-30');
  const extractResult = [];

  // 遍历每个卡片提取信息
  for (const card of cardHandles) {
    // 从当前卡片下查询子元素
    const coverImgHandle = await card.$('img');
    const titleHandle = await card.$('a h3');
    const detailLinkHandle = await card.$('a');

    // 提取对应属性,加空判避免部分卡片结构异常报错
    const coverImgUrl = coverImgHandle ? await page.evaluate(el => el.src, coverImgHandle) : null;
    const titleText = titleHandle ? await page.evaluate(el => el.textContent.trim(), titleHandle) : null;
    const detailPageUrl = detailLinkHandle ? await page.evaluate(el => el.href, detailLinkHandle) : null;

    extractResult.push({
      title: titleText,
      cover: coverImgUrl,
      detailUrl: detailPageUrl
    });

    // 手动销毁handle释放内存,非必需但推荐
    await coverImgHandle?.dispose();
    await titleHandle?.dispose();
    await detailLinkHandle?.dispose();
  }

  // 输出最终提取结果
  console.log(extractResult);
  // 关闭浏览器
  await browser.close();
})();

常见踩坑提醒

  • 不要混淆page.$和elementHandle.$:前者是从整个页面匹配元素,后者是从当前元素的子节点匹配
  • 所有DOM属性、文本的读取必须放到page.evaluate的回调中执行,ElementHandle只是Node侧的代理对象,本身不携带任何DOM属性
  • 遇到结构不固定的场景一定要加空判断,避免单条数据异常导致整个爬取流程中断

内容的提问来源于stack exchange,提问作者nikxtr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 05:12:00