如何在 Puppeteer node js 中使用 setinterval
How to use setinterval in Puppeteer node js
我想停止我的脚本并等到结束然后 return 阵列。如果没有 puppeteer 节点 js 中的 return 元素,它不应该向前移动。并没有等到clear interval再往前走,让我get undefined,这里怎么等数组的结果。
我得到的结果未定义。我想得到一个数组。
const puppeteer = require("puppeteer");
var page;
var browser;
async function getuser_data(callback) {
browser = await puppeteer.launch({
headless: false,
args: ["--no-sandbox", "--disable-setuid-sandbox"]
});
page = await browser.newPage();
await page.setViewport({
width: 1068,
height: 611
});
await page.goto(
"https://www.instagram.com/accounts/login/?source=auth_switcher"
);
await page.waitForSelector('input[name="username"]');
await page.type('input[name="username"]', "yourusername");
await page.type('input[name="password"]', "yourpassword");
await page.click("._0mzm-.sqdOP.L3NKy");
await page.waitFor(3000);
var y = "https://www.instagram.com/xyz/";
await page.goto(y);
await page.waitFor(2000);
var c = await page.evaluate(async () => {
await document
.querySelector(
"#react-root > section > main > div > header > section > ul > li:nth-child(2) > a"
)
.click();
var i = 0;
var timer = await setInterval(async () => {
i = i + 1;
console.log(i);
await document.querySelector(".isgrP").scrollBy(0, window.innerHeight);
var ele = await document.querySelectorAll(".FPmhX.notranslate._0imsa ")
.length;
console.log("Now length is :" + ele);
console.log("Timer :" + i);
if (ele > 10 && i > 20) {
console.log("Break");
clearInterval(timer);
console.log("after break");
var array = [];
for (var count = 1; count < ele; count++) {
try {
var onlyuname = await document.querySelector(
`body > div.RnEpo.Yx5HN > div > div.isgrP > ul > div > li:nth-child(${count}) > div > div.t2ksc > div.enpQJ > div.d7ByH > a`
).innerText;
console.log(onlyuname);
var obj = {
username: onlyuname
};
console.log(obj);
await array.push(obj);
} catch (error) {
console.log("Not found");
}
}
console.log(JSON.stringify(array));
return array; //Should Wait Till return , it should not move forward
}
}, 800);
});
console.log(c) //IT should return me array, Instead of undefined
callback(c)
}
getuser_data(users => {
console.log(users)
let treeusernamefile = JSON.stringify(users);
fs.writeFileSync('tablebay.json', treeusernamefile);
})
setTimeout
,promise 和递归函数可能会有帮助。
// a normal delay function, you can call this with await
const delay = d => new Promise(r => setTimeout(r, d))
const data = [];
async function timer(i = 0) {
// Optionally set to wait 1000 ms and then continue
await delay(1000)
// click element, grab data etc.
console.log(`Clicking element ${i}`);
data.push(i);
// check for condition fulfillment, you can basically put any limit here
if (i >= 10) return data;
// return another promise recursively here
return timer(i + 1)
}
timer().then(console.log)
运行 要查看的代码片段。它应该递归地显示控制台,直到达到某个限制。
它的工作方式是,如果条件尚未满足,它将 return 另一个承诺。您可以无限地调用它并清除超时(又名 return 数据而不是另一个计时器承诺)。
问题是 setInterval()
没有像您预期的那样工作。具体来说,它不会 return 一个 Promise
你可以 await
。它同步创建间隔,然后是您传递给 page.evaluate()
returns.
的整个函数
您需要做的是自己创建一个 Promise
并在您准备好 array
后告诉 resolve
。
//...
return new Promise((resolve, reject) => {
var timer = setInterval(async () => {
i = i + 1;
console.log(i);
await document.querySelector(".isgrP").scrollBy(0, window.innerHeight);
var ele = await document.querySelectorAll(".FPmhX.notranslate._0imsa ")
.length;
console.log("Now length is :" + ele);
console.log("Timer :" + i);
if (ele > 10 && i > 20) {
console.log("Break");
clearInterval(timer);
console.log("after break");
var array = [];
for (var count = 1; count < ele; count++) {
try {
var onlyuname = await document.querySelector(
`body > div.RnEpo.Yx5HN > div > div.isgrP > ul > div > li:nth-child(${count}) > div > div.t2ksc > div.enpQJ > div.d7ByH > a`
).innerText;
console.log(onlyuname);
var obj = {
username: onlyuname
};
console.log(obj);
await array.push(obj);
} catch (error) {
console.log("Not found");
}
}
console.log(JSON.stringify(array));
resolve(array); // <-----------------
}
}, 800);
})
//...
注意上面的例子没有处理错误。如果 setInterval
中的任何函数抛出异常,您需要捕获这些错误并将它们传递给 reject
.
的外部作用域
希望对您有所帮助。
我想停止我的脚本并等到结束然后 return 阵列。如果没有 puppeteer 节点 js 中的 return 元素,它不应该向前移动。并没有等到clear interval再往前走,让我get undefined,这里怎么等数组的结果。
我得到的结果未定义。我想得到一个数组。
const puppeteer = require("puppeteer");
var page;
var browser;
async function getuser_data(callback) {
browser = await puppeteer.launch({
headless: false,
args: ["--no-sandbox", "--disable-setuid-sandbox"]
});
page = await browser.newPage();
await page.setViewport({
width: 1068,
height: 611
});
await page.goto(
"https://www.instagram.com/accounts/login/?source=auth_switcher"
);
await page.waitForSelector('input[name="username"]');
await page.type('input[name="username"]', "yourusername");
await page.type('input[name="password"]', "yourpassword");
await page.click("._0mzm-.sqdOP.L3NKy");
await page.waitFor(3000);
var y = "https://www.instagram.com/xyz/";
await page.goto(y);
await page.waitFor(2000);
var c = await page.evaluate(async () => {
await document
.querySelector(
"#react-root > section > main > div > header > section > ul > li:nth-child(2) > a"
)
.click();
var i = 0;
var timer = await setInterval(async () => {
i = i + 1;
console.log(i);
await document.querySelector(".isgrP").scrollBy(0, window.innerHeight);
var ele = await document.querySelectorAll(".FPmhX.notranslate._0imsa ")
.length;
console.log("Now length is :" + ele);
console.log("Timer :" + i);
if (ele > 10 && i > 20) {
console.log("Break");
clearInterval(timer);
console.log("after break");
var array = [];
for (var count = 1; count < ele; count++) {
try {
var onlyuname = await document.querySelector(
`body > div.RnEpo.Yx5HN > div > div.isgrP > ul > div > li:nth-child(${count}) > div > div.t2ksc > div.enpQJ > div.d7ByH > a`
).innerText;
console.log(onlyuname);
var obj = {
username: onlyuname
};
console.log(obj);
await array.push(obj);
} catch (error) {
console.log("Not found");
}
}
console.log(JSON.stringify(array));
return array; //Should Wait Till return , it should not move forward
}
}, 800);
});
console.log(c) //IT should return me array, Instead of undefined
callback(c)
}
getuser_data(users => {
console.log(users)
let treeusernamefile = JSON.stringify(users);
fs.writeFileSync('tablebay.json', treeusernamefile);
})
setTimeout
,promise 和递归函数可能会有帮助。
// a normal delay function, you can call this with await
const delay = d => new Promise(r => setTimeout(r, d))
const data = [];
async function timer(i = 0) {
// Optionally set to wait 1000 ms and then continue
await delay(1000)
// click element, grab data etc.
console.log(`Clicking element ${i}`);
data.push(i);
// check for condition fulfillment, you can basically put any limit here
if (i >= 10) return data;
// return another promise recursively here
return timer(i + 1)
}
timer().then(console.log)
运行 要查看的代码片段。它应该递归地显示控制台,直到达到某个限制。
它的工作方式是,如果条件尚未满足,它将 return 另一个承诺。您可以无限地调用它并清除超时(又名 return 数据而不是另一个计时器承诺)。
问题是 setInterval()
没有像您预期的那样工作。具体来说,它不会 return 一个 Promise
你可以 await
。它同步创建间隔,然后是您传递给 page.evaluate()
returns.
您需要做的是自己创建一个 Promise
并在您准备好 array
后告诉 resolve
。
//...
return new Promise((resolve, reject) => {
var timer = setInterval(async () => {
i = i + 1;
console.log(i);
await document.querySelector(".isgrP").scrollBy(0, window.innerHeight);
var ele = await document.querySelectorAll(".FPmhX.notranslate._0imsa ")
.length;
console.log("Now length is :" + ele);
console.log("Timer :" + i);
if (ele > 10 && i > 20) {
console.log("Break");
clearInterval(timer);
console.log("after break");
var array = [];
for (var count = 1; count < ele; count++) {
try {
var onlyuname = await document.querySelector(
`body > div.RnEpo.Yx5HN > div > div.isgrP > ul > div > li:nth-child(${count}) > div > div.t2ksc > div.enpQJ > div.d7ByH > a`
).innerText;
console.log(onlyuname);
var obj = {
username: onlyuname
};
console.log(obj);
await array.push(obj);
} catch (error) {
console.log("Not found");
}
}
console.log(JSON.stringify(array));
resolve(array); // <-----------------
}
}, 800);
})
//...
注意上面的例子没有处理错误。如果 setInterval
中的任何函数抛出异常,您需要捕获这些错误并将它们传递给 reject
.
希望对您有所帮助。