【发布时间】:2021-02-19 09:22:05
【问题描述】:
这个小任务让我很头疼。
我只想让 puppeteer 访问游戏站点,然后等待 6 球结果出现在 Dom 中,然后获取每个球元素的 class[1] 及其互文,然后将其保存到 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")});
【问题讨论】:
标签: javascript node.js mongodb async-await puppeteer