情况:
我目前正在学习使用 puppeteer 进行抓取。
由于某种原因,我当前的代码给出了这个错误:
“UnhandledPromiseRejectionWarning:错误:评估失败:ReferenceError:页面未定义”
(编辑)
问题是,当页面加载并单击每个项目时,数据不会被抓取,因为代码似乎没有在单击每个项目后等待它加载。
以下是代码应该执行的操作:
加载网页(确定)
点击每个项目(确定)
每次单击某个项目时,都会在左侧的 div 中加载一些数据,这就是我要抓取的数据。 (目前不会发生)
为了实现这一点,我让代码在单击后等待 2 秒以加载数据。 (目前不会发生)
问题:
我该如何解决这个问题并适本地抓取所述数据?
代码:
const puppeteer = require('puppeteer');
let scrape = async () => {
const browser = await puppeteer.launch({headless: false});
const page = await browser.newPage();
await page.goto('https://website.com');
await page.setViewport({width: ..., height: ...});
const result = await page.evaluate(() => {
let data = [];
let elements = document.querySelector('.class1').querySelectorAll('.class2');
for (var element of elements){
page.click(element);
page.waitFor(2000);
let 1 = document.querySelector('.class0').querySelector('.class3').getAttribute("data-1");
let 2 = document.querySelector('.class0').querySelector('.class4').innerText;
let 3 = document.querySelector('.class0').querySelector('.class5').innerText;
let 4 = document.querySelector('.class0').querySelector('.class6').innerText;
data.push({1: 1, 2: 2, 3: 3, 4: 4}); // Push an object with the data onto our array
}
return data; // Return our data array
});
browser.close();
return result; // Return the data
};
scrape().then((value) => {
console.log(value); // Success!
});
最佳答案
此代码存在一些问题:
1
、2
等不是有效的标识符(不过我猜这只是为了示例).click()
和.waitFor()
会返回 Promise,您不会等待,但无论如何......- 您传递给
evaluate
的函数是在页面上下文中计算的,而不是 Node.JS 代码,因此page
不存在
相反,您可以直接在函数中与页面交互,就像您已经做的那样:
const puppeteer = require('puppeteer');
let scrape = async () => {
const browser = await puppeteer.launch({ headless: false });
const page = await browser.newPage();
await page.goto('https://website.com');
await page.setViewport({ width: ..., height: ... });
const result = await page.evaluate(async () => {
const data = [];
const elements = document.querySelector('.class1').querySelectorAll('.class2');
for (const element of elements) {
element.click();
await new Promise((resolve) => setTimeout(resolve, 2000));
const one = document.querySelector('.class0').querySelector('.class3').getAttribute("data-1");
const two = document.querySelector('.class0').querySelector('.class4').innerText;
const three = document.querySelector('.class0').querySelector('.class5').innerText;
const four = document.querySelector('.class0').querySelector('.class6').innerText;
data.push({ 1: 1, 2: 2, 3: 3, 4: 4 }); // Push an object with the data onto our array
}
return data; // Return our data array
});
browser.close();
return result; // Return the data
};
scrape().then((value) => {
console.log(value); // Success!
});
关于javascript - 如何点击所有元素并等待每个元素完成 AJAX 请求以抓取数据? (AJAX每次都加载到同一个元素中),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51448914/