Puppeteer中page.$$与page.$$eval的区别及元素操作问题咨询
page.$$与page.$$eval的核心区别
page.$$(selector):执行于Node.js环境,返回Puppeteer封装的ElementHandle对象数组,每个实例对应浏览器中的一个DOM元素,支持调用click()、type()等Puppeteer提供的元素操作方法。但该对象不是原生DOM对象,无法直接读取innerHTML等DOM原生属性,需要额外调用方法从浏览器侧拉取属性值。page.$$eval(selector, pageFunction):第二个参数pageFunction回调执行于浏览器侧,返回值会经过JSON序列化后才传回Node.js环境。由于DOM元素属于浏览器宿主对象,本身不支持序列化,直接返回DOM元素会得到无属性无方法的空对象,只有字符串、数字、普通JS对象这类可序列化的值才能正常传回。
代码错误原因
你在$$eval回调中直接返回DOM元素的操作不符合接口设计要求,序列化过程完全丢失了DOM元素的属性和方法,因此拿到的elNum数组中的元素都是无效空对象,自然无法调用click()方法,也读取不到innerHTML属性。
同时获取元素操作权限与innerHTML的实现方案
先用page.$$拿到ElementHandle数组满足操作需求,需要读取DOM属性时调用ElementHandle的evaluate方法拉取浏览器侧的属性值即可,示例代码如下:
// 1. 获取ElementHandle数组,支持元素操作 const grabElements = await page.$$(selector); // 执行点击操作 await grabElements[0].click(); // 2. 读取单个元素的innerHTML const firstElInnerHTML = await grabElements[0].evaluate(dom => dom.innerHTML); // 3. 批量获取所有元素的innerHTML const allInnerHTMLList = await Promise.all( grabElements.map(el => el.evaluate(dom => dom.innerHTML)) );
内容的提问来源于stack exchange,提问作者BrainLag
相关产品推荐
相关产品推荐

