首页 > 解决方案 > Puppeteer 的 page.evaluate 不考虑 i 在 for 循环中

问题描述

我一直在尝试遍历一个 div 列表,除了其中显示的数据之外几乎相同,它们位于 dom 的某个部分下<aside>,以便从每个部分中获取 innerText。结果在对数字进行硬编码时可以正常运行nth-child,但是,尝试在 for 循环中对其进行迭代会产生错误:Error: Evaluation failed: ReferenceError: i is not defined at __puppeteer_evaluation_script__:1:130. 对这里发生的事情感到困惑。

    for (let i = 1; i < 9; i++) {
        let info = await page.evaluate(
            () => [...document.querySelectorAll(`#root > main > div.sc-jcVebW.eVwwrC > div.sc-bZSQDF.dgraCx > div > aside > div:nth-child(${i}) > div.sc-dlfnbm.ujoHC > div.sc-hKgILt.beOqPu > div > h2`)].map(elem => elem.innerText)
        );
        console.log(info)
    }

标签: javascriptnode.jspuppeteer

解决方案


传递给page.evaluate字符串化的函数以便它们可以在浏览器中运行,因此它们没有通常期望的词法范围继承。您需要传递另一个参数page.evaluate来指示函数应采用的参数。

我还建议使代码更具可读性:将长选择器放在自己的行上,并使用const代替let(如果可能的话):

const info = await page.evaluate(
    (i) => {
        const selector = `#root > main > div.sc-jcVebW.eVwwrC > div.sc-bZSQDF.dgraCx > div > aside > div:nth-child(${i}) > div.sc-dlfnbm.ujoHC > div.sc-hKgILt.beOqPu > div > h2`;
        return [...document.querySelectorAll(selector)]
           .map(elem => elem.innerText);
    },
    i
);

还要考虑是否.innerText真的是你需要的——它通常不是.textContent如果可以,请改用。


推荐阅读