无法让 querySelectorAll 与 puppeteer 一起使用(返回未定义)

Kas*_*sen 3 javascript puppeteer queryselector

我正在尝试根据超市的价格进行一些网络抓取。它与 Node.js 和 puppeteer 一起使用。我可以通过接受 cookie 并单击“加载更多按钮”开始浏览网站。但是当我尝试使用 querySelectorAll 读取包含产品的 div 时,我陷入了困境。即使我等待特定的 div 出现,它也会返回未定义。我缺少什么?

\n

问题出在代码块的末尾。

\n
const { product } = require("puppeteer");\n\nconst scraperObjectAll = {\n    url: 'https://www.bilkatogo.dk/s/?query=',\n    async scraper(browser) {\n        let page = await browser.newPage();\n        console.log(`Navigating to ${this.url}`);\n        await page.goto(this.url);\n\n        // accept cookies\n        await page.evaluate(_ => {\n            CookieInformation.submitAllCategories();\n        });\n\n        var productsRead = 0;\n        var productsTotal = Number.MAX_VALUE;\n\n        while (productsRead < 100) {\n            // Wait for the required DOM to be rendered\n            await page.waitForSelector('button.btn.btn-dark.border-radius.my-3');\n            // Click button to read more products\n            await page.evaluate(_ => {\n                document.querySelector("button.btn.btn-dark.border-radius.my-3").click()\n            });\n            // Wait for it to load the new products\n            await page.waitForSelector('div.col-10.col-sm-4.col-lg-2.text-center.mt-4.text-secondary');\n            // Get number of products read and total\n            const loadProducts = await page.evaluate(_ => {\n                let p = document.querySelector("div.col-10.col-sm-4.col-lg-2").innerText.replace("INDL\xc3\x86S FLERE", "").replace("Du har set ","").replace(" ", "").replace(/(\\r\\n|\\n|\\r)/gm,"").split("af ");\n                return p;\n            });\n\n            console.log("Products (read/total): " + loadProducts);\n            productsRead = loadProducts[0];\n            productsTotal = loadProducts[1];\n\n            // Now waiting for a div element\n            await page.waitForSelector('div[data-productid]');\n\n            const getProducts = await page.evaluate(_ => {\n                return document.querySelectorAll('div');\n            });\n\n            // PROBLEM HERE!\n            // Cannot convert undefined or null to object\n            console.log("LENGTH: " + Array.from(getProducts).length);\n        }\n
Run Code Online (Sandbox Code Playgroud)\n

Cer*_*nce 6

传递给的回调page.evaluate模拟页面上下文中运行,而不是在 Node 脚本的标准范围内运行。如果不仔细考虑,则无法在页面和 Node 脚本之间传递表达式:最重要的是,如果某些内容不可序列化(转换为纯 JSON),则无法传输。

querySelectorAll返回一个NodeList,NodeList只存在于前端,后端不存在。同样,NodeLists包含HTMLElements,它们也只存在于前端。

将所有需要使用仅存在于前端的数据的逻辑放在回调中.evaluate,例如:

const numberOfDivs = await page.evaluate(_ => {
  return document.querySelectorAll('div').length;
});
Run Code Online (Sandbox Code Playgroud)

或者

const firstDivText = await page.evaluate(_ => {
  return document.querySelector('div').textContent;
});
Run Code Online (Sandbox Code Playgroud)