这个小任务真让我头疼。
我只想让木偶人访问游戏站点,然后等待6个球的结果出现在Dom中,然后获取每个球元素的class1和它们的互文,然后将其保存到mongo dB数据库。
当我运行node index.js时,它只工作了一次。但我想做的是,一旦异步函数运行并获取数据并将其发送到数据库,我希望它要么等待3-5秒,然后再次运行。并继续重复同样的过程。
-访问游戏网站-刮掉6个球的结果-将结果保存到数据库-然后再次从步骤1开始重复。
我不想使用setInterval,因为我真的不知道异步函数什么时候会完成它的过程。
所以我只是在寻找一种方法,可以让异步函数在运行时返回一个值,所以根据返回的值,我可以知道它已经完成了任务,然后我将再次运行它。
我已经包含了我尝试过的解决方案,但结果并不稳定。iife方法只运行两次。.then promise方法根本不起作用,我注释掉了下面的两个解决方案
我做错了什么??或者可能是scrapedata函数本身写得不好。谁来帮我改正一下。
var http = require("http");
const mongoose = require("mongoose");
const puppeteer = require("puppeteer");
mongoose.connect("mongodb://localhost:27017/gameDb", { useNewUrlParser: true, useUnifiedTopology: true, });
const gameSchema = new mongoose.Schema({time: String, ball1color: String, ball1number: Number, ball2color: String, ball2number: Number, ball3color: String, ball3number: Number, ball4color: String, ball4number: Number, ball5color: String, ball5number: Number, ball6color: String, ball6number: Number});
async function scrapeData(url){
const browser = await puppeteer.launch({ headless:false, args: ['--no-sandbox'] });
const page = await browser.newPage();
await page.goto(url);
//wait for the elements that i want to scrape to become visible in the Dom
await page.waitForFunction(()=>{
return document.querySelectorAll('.ball')[2] && document.querySelectorAll('.ball')[2].style.visibility != 'hidden' && document.querySelectorAll('.ball')[3] && document.querySelectorAll('.ball')[3].style.visibility != 'hidden' && document.querySelectorAll('.ball')[4] && document.querySelectorAll('.ball')[4].style.visibility != 'hidden' && document.querySelectorAll('.ball')[5] && document.querySelectorAll('.ball')[5].style.visibility != 'hidden' && document.querySelectorAll('.ball')[6] && document.querySelectorAll('.ball')[6].style.visibility != 'hidden' && document.querySelectorAll('.ball')[7] && document.querySelectorAll('.ball')[7].style.visibility != 'hidden';
}, {timeout: 100000 });
//wait for the innertext of the 6 balls to appear
await page.waitForFunction(() => {
return document.querySelectorAll(".ball")[2].innerText !== '' && document.querySelectorAll(".ball")[3].innerText !== '' && document.querySelectorAll(".ball")[4].innerText !== '' && document.querySelectorAll(".ball")[5].innerText !== '' && document.querySelectorAll(".ball")[6].innerText !== '' && document.querySelectorAll(".ball")[7].innerText !== '';
}, { timeout: 100000 });
//get the color and no of the six balls starting from the left
const [ball1, ball2, ball3, ball4, ball5, ball6] = await page.evaluate(() => {
const ball1 = document.querySelectorAll(".ball")[2]; const ball2 = document.querySelectorAll(".ball")[3];
const ball3 = document.querySelectorAll(".ball")[4]; const ball4 = document.querySelectorAll(".ball")[5];
const ball5 = document.querySelectorAll(".ball")[6]; const ball6 = document.querySelectorAll(".ball")[7];
//return the color and their numbers
return [
{number: ball1.innerText,color: ball1.classList[1].split('-')[1]},{number: ball2.innerText,color: ball2.classList[1].split('-')[1]},
{number: ball3.innerText,color: ball3.classList[1].split('-')[1]},{number: ball4.innerText,color: ball4.classList[1].split('-')[1]},
{number: ball5.innerText,color: ball5.classList[1].split('-')[1]},{number: ball6.innerText,color: ball6.classList[1].split('-')[1]}
];
});
var gotData;
//convert time to nigeria timezone
function convertTZ(date, tzString) {
return new Date((typeof date === "string" ? new Date(date) : date).toLocaleString("en-US", {timeZone: tzString}));
}
const convertDate = convertTZ(new Date(),"Africa/Lagos");
//change convert getMonth() to human readable formart
var thisMonth;
switch(convertDate.getMonth()){ case 0: thisMonth = "january"; break; case 1: thisMonth = "february"; break; case 2: thisMonth = "march"; break; case 3: thisMonth = "april"; break; case 4: thisMonth = "may"; break; case 5: thisMonth = "june"; break; case 6: thisMonth = "july"; break; case 7: thisMonth = "august"; break; case 8: thisMonth = "september"; break; case 9: thisMonth = "octomber"; break; case 10: thisMonth = "november"; break; case 11: thisMonth = "december"; break; default: thisMonth = "invalid_month";}
//create a db collection, name it using today date & month in nigeria timezone
var dbCollection = thisMonth+"_"+convertDate.getDate();
//get the current time in Nigeria timezone & save it to a variable
const gameTime = convertDate.getHours()+":"+convertDate.getMinutes()+":"+convertDate.getSeconds();
//write the result to the database
const collection = mongoose.model(dbCollection, gameSchema);
const Result = new collection({
time: gameTime, ball1color: ball1.color, ball1number: ball1.number,
ball2color: ball2.color, ball2number: ball2.number,
ball3color: ball3.color, ball3number: ball3.number,
ball4color: ball4.color, ball4number: ball4.number,
ball5color: ball5.color, ball5number: ball5.number,
ball6color: ball6.color, ball6number: ball6.number,
});
Result.save((err, savedDoc, rowsAffected)=>{
if(err){
gotData = false;
//return gotData;
}else{
gotData = true;
//return gotData;
}
});
//close the browser
await browser.close();
return gotData;
}
// scrapeData("https://logigames.bet9ja.com/Games/Launcher?gameId=11000&provider=0&sid=&pff=1&skin=201").then(isSaved)=>{
// if(isSaved == true){
// scrapeData("https://logigames.bet9ja.com/Games/Launcher?gameId=11000&provider=0&sid=&pff=1&skin=201");
// }else if(isSaved == false){
// scrapeData("https://logigames.bet9ja.com/Games/Launcher?gameId=11000&provider=0&sid=&pff=1&skin=201");
// }else{
// console.log(isSaved + " something is really wrong");
// }
// });
// (async ()=>{
// const isSaved = await scrapeData("https://logigames.bet9ja.com/Games/Launcher?gameId=11000&provider=0&sid=&pff=1&skin=201");
// if(isSaved == true){
// scrapeData("https://logigames.bet9ja.com/Games/Launcher?gameId=11000&provider=0&sid=&pff=1&skin=201");
// }else if(isSaved == false){
// scrapeData("https://logigames.bet9ja.com/Games/Launcher?gameId=11000&provider=0&sid=&pff=1&skin=201");
// }else{
// console.log(isSaved + " something is really wrong");
// }
// })();
http.createServer((request, response)=>{
if(request.url == "/" && request.method == "GET"){
response.writeHead(200, { 'Content-Type': 'text/html' });
response.end("your app is working", "utf-8");
}
}).listen(process.env.PORT || 3000,()=>{console.log("server working")});
发布于 2021-02-19 09:15:50
,我想让它等待3-5秒,然后再运行一次。并继续重复同样的过程。
只需使用while循环和promisified setTimeout:
const wait = ms => new Promise(r => setTimeout(r, ms));
(async => {
while (true) {
const isSaved = await scrapeData(url);
// ...
await wait(5000);
}
})();
发布于 2021-02-19 01:03:44
这里有四个任务。请注意,它们都是async
函数。函数的内部工作可以是同步的,也可以是异步的。
start()
函数是递归的。它使用链式将每个任务按顺序排列。等待函数是可以调整的简单超时。
在这个例子中,我在四次迭代后停止它。通过删除条件,它可以连续运行。
注意:您必须释放在每个任务方法中创建的任何资源。如果你不小心自己清理的话,这个代码很容易发生内存泄漏。在每个任务的返回语句之前,将函数中创建的所有对象设置为null
。
async function doTask1() {
console.log('doing task1...');
return true;
}
async function doTask2() {
console.log('doing task2...');
return true;
}
async function doTask3() {
console.log('doing task3...');
return true;
}
async function doTask4() {
console.log('doing task4...');
return true;
}
function wait() {
return new Promise((res, rej) => {
if (counter < 3) {
console.log('----- waiting -----');
counter++;
setTimeout(res, 2000);
} else {
console.log('----- DONE -----');
rej();
}
});
}
let counter = 0;
function start() {
doTask1().then(doTask2).then(doTask3).then(doTask4).then(wait).then(start);
}
start();
https://stackoverflow.com/questions/66263451
复制相似问题