我一直在尝试实现一个Web抓取工具,该抓取工具将使用从MongoDB中提取的数据来创建一组URL,以定期使用puppeteer进行抓取。我一直在尝试使用setIntervalAsync使我的刮板功能定期进行刮板。
这里是我的代码,现在抛出“ UnhandledPromiseRejectionWarning:TypeError:无法将未定义或null转换为Function.values上的对象...”
puppeteer.js
async function scrape(array){
// initialize for loop here
let port = '9052'
if(localStorage.getItem('scrapeRunning')=='restart'){
clearIntervalAsync(scrape)
localStorage.setItem('scrapeRunning') == 'go'
}else if(localStorage.getItem('scrapeRunning') != 'restart'){
/// Puppeteer scrapes urls in array here ///
}
server.js
app.post('/submit-form', [
// Form Validation Here //
], (req,res)=>{
async function submitForm(amazonUrl,desiredPrice,email){
// Connect to MongoDB and update entry or create new entry
// with post request data
createMongo.newConnectToMongo(amazonUrl,desiredPrice,email)
.then(()=>{
// Set local variable that will alert scraper to clearIntervalAsync///
localStorage.setItem('scrapeRunning','restart');
// before pulling the new updated mongoDB data ...
return createMongo.pullMongoArray();
})
.then((result)=>{
// and start scraping again with the new data
puppeteer.scrape(result)
})
submitForm(req.body.amazonUrl, req.body.desiredPrice,req.body.email);
}
}
createMongo.pullMongoArray()
.then((result)=>{
setIntervalAsync(puppeteer.scrape, 10000, result);
})
当前,刮板在启动服务器后将按预期方式启动,并且在刮板结束与再次开始之间保持10秒钟的时间。一旦有帖子提交,MongoDB集合将使用帖子数据进行更新,则将创建localStorage项,但是scrape函数将脱离常规并引发typeError。我不知道发生了什么,并尝试了多种方法来解决此问题(包括将setIntervalAsync和clearIntervalAsync保留在请求后代码块中),但到目前为止仍未成功。我对编码有些陌生,并且对异步代码非常缺乏经验,因此,如果有人对这种问题有任何经验,并且可以对正在发生的事情有所了解,我将不胜感激!
我只认为它与异步有关,无论我尝试过什么,它似乎也在newConnectToMongo函数完成之前运行pullMongoArray函数。
经过几个小时的搜索,我认为我可能已经找到了可行的解决方案。我已经完全取消了localStorage的使用,并从scrape函数中删除了if和else if语句。我还制作了一个全局计时器变量,并向该文件添加了控制功能。
puppeteer.js
let timer;
function start(result){
timer = setIntervalAsync(scrape,4000, result)
}
function stop(){
clearIntervalAsync(timer)
}
async function scrape(array){
// initialize for loop here
let port = '9052'
// Puppeteer scrapes urls from array here //
}
我已经稍微修改了服务器代码,因此在服务器启动时,它会从MongoDB获取结果,并将其用于刮板启动功能。在更新MongoDB之前,发布请求还调用stop函数,从MongoDB中获取新结果,然后调用start scraper函数。
server.js
createMongo.pullMongoArray()
.then((result)=>{
puppeteer.start(result);
})
app.post('/submit-form', [
// Form Validation In Here //
], (req,res)=>{
async function submitForm(amazonUrl,desiredPrice,email){
// Stop the current instance of the scrape function
puppeteer.stop();
// Connect to MongoDB and update entry or create new entry
// with post request data
createMongo.newConnectToMongo(amazonUrl,desiredPrice,email)
.then(()=>{
// before pulling the new updated mongoDB data ...
console.log('Pulling New Array');
return createMongo.pullMongoArray();
})
.then((result)=>{
// and restarting the repeating scrape function
puppeteer.start(result);
})
}
})