gpt4 book ai didi

javascript - 如何从另一个 JavaScript 函数定期终止和重启一个 JavaScript 函数

转载 作者:搜寻专家 更新时间:2023-11-01 00:30:02 25 4
gpt4 key购买 nike

我编写了一个爬虫,它遍历网站上的每个页面并提取信息。有很多页;如果这个程序不停地运行,大约需要一个星期才能完成。但是,每隔两三个小时它就会在尝试从页面中提取信息时挂起,并且永远不会继续。这令人沮丧,因为我一直不得不重新启动脚本。这是它的框架,使用 NodeJS 运行:

index = 0;
finalIndex = 50000;

function scrape(){
if(index < finalIndex){
//hit the website using nightmare, navigate to page, extract info, store as JSON
console.log("finished scraping page number: ", index);
index++;
scrape();
}
}

scrape();

我想在这个文件或另一个文件中有一个运行抓取功能的函数,然后每 2 小时终止该函数并从它试图从中抓取的最后一个索引重新启动它。我试过考虑使用 setTimeout 的公式,但我不确定如何中途终止函数堆栈。如果抓取功能已经开始挂起,我也不希望重新启动功能失败。

执行此操作的最佳方法是什么?欢迎使用此问题的其他解决方案,但即使从 JavaScript 知识的 Angular 来看,我也想知道将来如何解决这个问题。

这是我的函数的更详细信息:

function scrape() {
console.log("initializing scrape from index: " + index);
var nightmare = Nightmare();
if (index < indexEnd) {

nightmare
.goto(hidTestURL) //connect to the main site
.wait('input[name="propertySearchOptions:advanced"]')
.wait(4000)
.goto(pageURL) //navigate to the specific entry's info page
.wait('a[id="propertyHeading_searchResults"]')
.wait(2500)
.evaluate(function(){
return document.querySelector('body').innerHTML;
})
.then(function(html){
return xP([html, {data: css.data}])() //scrape the data from the page
})
.then(cleanDetails)
.then(writeResult)
.then(_ => {
nightmare.end();
nightmare.proc.disconnect();
nightmare.proc.kill();
nightmare.ended = true;
nightmare = null;
})
.then(function(){
console.log("successful scrape for ", ids[index]);
++index;
setTimeout(scrape(), interval); //start scraping the next entry after a specified delay (default 4 seconds)
})
.catch(function(e){
if (e.message === 'EmptyProperty'){
console.log('EmptyProperty');
++index;
setTimeout (scrape, interval / 2);
}
else {
return appendFileP(logFile, new Date().toString() + " unhandled error at " + street + index + ' ' + e + '\r\n', 'utf8')
.then(function(){
if (numOfTries < 2){
console.log("Looks like some other error, I'll retry: %j", e.message);
++numOfTries;
setTimeout (scrape, interval * 5);
return nightmare.end();
}
else {
console.log("Tried 3 times, moving on");
++index;
numOfTries = 0;
setTimeout (scrape, interval * 5);
return nightmare.end();
}
});
}
})

}

有些辅助函数的代码我没有包括在内,但它们的名字应该很明显,而且我认为它们的功能不是问题的重要部分。我还想明确表示,我正在使用 Node 运行它,它永远不会在浏览器中运行。

最佳答案

我之前不得不解决类似的问题,我选择的解决方案是确保每个页面在一定时间内完成,否则继续下一页。您可以将噩梦代码包装在一个 promise 中,并使用 Promise.race 来确保它在设定的时间内完成。然后,如果超时,使用在 v2.8.0 中引入的 .halt api以防止内存泄漏和废弃进程。

它看起来像这样:

Promise.race([
doNightmareCodeAndReturnPromise(nightmareInstance),
new Promise((resolve, reject) => setTimeout(() => reject('timed out'), 5000))
])
.then(result => /* save result */)
.catch(error => {
if (error === 'timed out') nightmareInstance.halt()
})

关于javascript - 如何从另一个 JavaScript 函数定期终止和重启一个 JavaScript 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40007105/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com