Puppeteer page.$$(selector)

发布于:2025-07-06 ⋅ 阅读:(21) ⋅ 点赞:(0)

在 Puppeteer 中,page.$$(selector) 是一个用于在页面上选择多个元素的方法,它返回一个由 ElementHandle 组成的数组(Promise<Array<ElementHandle>>)。与 page.$$eval() 不同,page.$$() 不会自动执行回调函数,而是返回可进一步操作的 ElementHandle 对象。


基本语法

javascript

const elements = await page.$$(selector);
  • selector: CSS 选择器(如 'a''.class''#id')。

  • 返回值Promise<Array<ElementHandle>>,解析为匹配的所有元素的 ElementHandle 数组。


核心用途

  1. 获取元素列表:选择多个元素后,可以遍历或单独操作。

  2. 结合其他方法:对每个元素执行点击、输入、截图等操作(需配合 ElementHandle 的方法)。


常见用法示例

1. 获取所有链接的 ElementHandle

javascript

const links = await page.$$('a'); // 获取所有 <a> 元素
console.log(links.length); // 输出匹配的元素数量
2. 遍历元素并操作

javascript

const buttons = await page.$$('button');
for (const button of buttons) {
  await button.click(); // 点击每个按钮
  await page.waitForTimeout(500); // 可选:延迟
}
3. 提取元素属性(需结合 evaluate

javascript

const elements = await page.$$('img');
const srcList = await Promise.all(
  elements.map(img => img.evaluate(el => el.src))
);
console.log(srcList); // 输出所有图片的 src 属性
4. 过滤可见元素

javascript

const allLinks = await page.$$('a');
const visibleLinks = [];
for (const link of allLinks) {
  const isVisible = await link.evaluate(el => 
    el.offsetWidth > 0 && el.offsetHeight > 0
  );
  if (isVisible) visibleLinks.push(link);
}
console.log(visibleLinks.length);

与 page.$$eval() 的区别

方法 返回值 适用场景
page.$$(selector) ElementHandle[](可进一步操作) 需要逐个操作元素(如点击、截图)
page.$$eval() 直接返回回调函数的结果 快速提取数据或批量修改属性

示例对比

javascript

// 使用 $$eval 直接提取文本
const texts = await page.$$eval('a', els => els.map(el => el.textContent));

// 使用 $$ 获取 ElementHandle 后提取文本
const links = await page.$$('a');
const texts = await Promise.all(
  links.map(link => link.evaluate(el => el.textContent))
);

注意事项

  1. 元素可能动态加载:建议先使用 page.waitForSelector 确保元素存在:

    javascript

    await page.waitForSelector('a');
    const links = await page.$$('a');
  2. ElementHandle 需手动释放:长时间运行的脚本应调用 elementHandle.dispose() 防止内存泄漏。

  3. 性能优化:如果只需提取数据,$$eval 比 $$ + evaluate 更高效。


高级用法

与 page.waitForXPath 结合(XPath 选择器)

javascript

const items = await page.$x('//div[@class="item"]'); // XPath 选择
for (const item of items) {
  await item.click();
}
截图多个元素

javascript

const images = await page.$$('img');
for (let i = 0; i < images.length; i++) {
  await images[i].screenshot({ path: `image_${i}.png` });
}

总结

  • page.$$() 适合需要对元素逐个操作的场景(如点击、截图、动态判断)。

  • page.$$eval() 适合快速提取数据或批量修改属性。

  • 如果遇到元素选择问题,可结合 page.waitForSelector 或调整选择器(如 :visible 伪类模拟)。


网站公告

今日签到

点亮在社区的每一天
去签到