0

I've been trying to iterate over a list of divs, nearly identical besides the data displayed in them, that are under a certain section of the dom, <aside>, in order to grab the innerText from each one of them. The result functions properly when hardcoding an nth-child number, however, trying to iterate it in a for loop produces the error: Error: Evaluation failed: ReferenceError: i is not defined at __puppeteer_evaluation_script__:1:130. Confused as to what's going on here.

    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)
    }
Krom
  • 11
  • 1

1 Answers1

0

Functions passed to page.evaluate get stringified so they can be run in the browser, so they don't have lexical scope inheritance that one would normally expect. You need to pass another argument to page.evaluate to indicate the parameters the function should take.

I'd also recommend making the code more readable: put the long selector on its own line, and use const instead of let (if at all possible):

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
);

Also consider if .innerText is really what you need - it usually isn't. Use .textContent instead if you can.

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320