关于puppeteer的方法$$eval里用不了nanoid生成的id?

大佬们,我使用puppeteer里的方法$$eval去爬一下页面的数据,结果发现引入的nanoid不能使用,刚开始还以为是nanoid不支持commonJS写法导致的,结果调试发现在eval函数外使用可以打印成功,eval里使用就报错了
注意:$$eval返回一个promise

async callback(pg) {
        console.log(nanoid());//这里能打印出来
        const imgList = await pg.$$eval('div.swiper-wrapper>div.swiper-slide>div>img', els => els.map((el, index) => {
            return {
                imgUrl: el.src,
                alt: '图片',
                id: index,
                imgKey:nanoid()//这里不能使用nanoid
            }
        })) || []
        return imgList
    }

报的错误:

node:internal/process/promises:279
            triggerUncaughtException(err, true /* fromPromise */);
            ^

Error [ReferenceError]: nanoid is not defined
pptr:$$eval;Object.callback%20(D%3A%5C%E9%A1%B9%E7%9B%AE%5C%E7%88%AC%E8%99%AB%E7%B3%BB%E7%BB%9F%5Ccrawler%5Ccrawlers%5Cslider.js%3A8%3A34):6:24
    at $$eval ($$eval at Object.callback (D:\项目\爬虫系统\crawler\crawlers\slider.js:8:34), <anonymous>:5:23)
    at $$eval ($$eval at Object.callback (D:\项目\爬虫系统\crawler\crawlers\slider.js:8:34), <anonymous>:0:12)
    at ExecutionContext.#evaluate (D:\项目\爬虫系统\crawler\node_modules\puppeteer-core\lib\cjs\puppeteer\common\ExecutionContext.js:254:55)
    at async ExecutionContext.evaluate (D:\项目\爬虫系统\crawler\node_modules\puppeteer-core\lib\cjs\puppeteer\common\ExecutionContext.js:151:16)
    at async CDPJSHandle.evaluate (D:\项目\爬虫系统\crawler\node_modules\puppeteer-core\lib\cjs\puppeteer\common\JSHandle.js:48:16)
    at async Promise.all (index 0)
    at async CDPElementHandle.$$eval (D:\项目\爬虫系统\crawler\node_modules\puppeteer-core\lib\cjs\puppeteer\api\ElementHandle.js:227:26)
    at async Object.callback (D:\项目\爬虫系统\crawler\crawlers\slider.js:8:25)
    at async module.exports (D:\项目\爬虫系统\crawler\libs\crawler.js:10:18)

有大佬知道为什么吗

阅读 1.1k
avatarAI BotBETA

根据您提供的代码和错误信息,问题出在您在执行$$eval`函数时使用的变量`imgKey`上。`$$eval函数期望传递一个函数,该函数接收三个参数:一个ExecutionContext对象、一个数组和一个回调函数。

然而,您在调用$$eval时,将一个变量(imgKey)作为数组传递给了它。这导致Puppeteer无法正确地识别该变量,从而引发了错误。

要解决这个问题,您可以将变量转换为数组,然后再传递给$$eval函数。以下是修改后的代码示例:

async callback(pg) {
    console.log(nanoid()); // 这里能打印出来
    const imgList = await pg.$$eval('div.swiper-wrapper>div.swiper-slide>div>img', els => els.map((el, index) => {
        return {
            imgUrl: el.src,
            alt: '图片',
            id: index,
            imgKey: [index, nanoid()] // 修改这一行
        }
    })) || []
    return imgList
}

在这个修改后的代码中,我们将imgKey变量的值更改为包含索引和nanoid()生成的ID的数组。这样,当Puppeteer调用$$eval函数时,它将正确地识别到这个数组,从而不再引发错误。

1 个回答

你这么写试试:

async callback(pg) {
        console.log(nanoid());//这里能打印出来
        const imgList = await pg.$$eval('div.swiper-wrapper>div.swiper-slide>div>img', (els,nid) => els.map((el, index) => {
            return {
                imgUrl: el.src,
                alt: '图片',
                id: index,
                imgKey:nid()//这里不能使用nanoid
            }
        }),nanoid) || []
        return imgList
    }

文档中说,要使用第三个参数传入
image.png
https://zhaoqize.github.io/puppeteer-api-zh_CN/#?product=Puppeteer&version=puppeteer-v21.2.1&show=api-pageevalselector-pagefunction-args

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题