Kas*_*sen 3 javascript puppeteer queryselector
我正在尝试根据超市的价格进行一些网络抓取。它与 Node.js 和 puppeteer 一起使用。我可以通过接受 cookie 并单击“加载更多按钮”开始浏览网站。但是当我尝试使用 querySelectorAll 读取包含产品的 div 时,我陷入了困境。即使我等待特定的 div 出现,它也会返回未定义。我缺少什么?
\n问题出在代码块的末尾。
\nconst { 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 }\nRun Code Online (Sandbox Code Playgroud)\n
传递给的回调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)
| 归档时间: |
|
| 查看次数: |
3680 次 |
| 最近记录: |