Puppeteer page.$$(selector)
在 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
数组。
核心用途
-
获取元素列表:选择多个元素后,可以遍历或单独操作。
-
结合其他方法:对每个元素执行点击、输入、截图等操作(需配合
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)) );
注意事项
-
元素可能动态加载:建议先使用
page.waitForSelector
确保元素存在:javascript
await page.waitForSelector('a'); const links = await page.$$('a');
-
ElementHandle
需手动释放:长时间运行的脚本应调用elementHandle.dispose()
防止内存泄漏。 -
性能优化:如果只需提取数据,
$$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
伪类模拟)。