javascript – 梦魇条件等待()
作者:互联网
我正在尝试使用Nightmare抓取网页,但是想要等待#someelem存在,只有它确实存在.否则,我想让梦魇继续前进.如何使用.wait()来完成?
我不能使用.wait(ms).使用.wait(选择器)意味着Nightmare将一直等到元素存在,但如果页面永远不会有这个元素,Nightmare将永远等待.
最后一个选项是使用.wait(fn).我尝试过这样的事情
.wait(function(cheerio) {
var $= cheerio.load(document.body.outerHTML);
var attempt = 0;
function doEval() {
if ( $('#elem').length > 0 ) {
return true;
}
else {
attempt++;
if ( attempt < 10 ) {
setTimeout(doEval,2000); //This seems iffy.
}
else {
return true;
}
}
}
return doEval();
},cheerio)
所以,等待并再次尝试(达到阈值),如果找不到元素,那么继续前进. setTimeout周围的代码似乎是错误的,因为.wait是在浏览器范围内完成的.
提前致谢!
解决方法:
我不认为通过cheerio库你会有很好的工作.参数被序列化(或多或少)传递给子Electron进程,因此传递整个库可能不起作用.
另一方面,.wait(fn)的fn部分在页面上下文中执行 – 这意味着您可以完全访问文档及其拥有的方法(例如,querySelector).您也可以访问该页面的jQuery上下文(如果存在),或者甚至可以使用.inject()注入它.
除此之外,你是正确的.因为.wait()(和.evaluate(),就此而言)期望一个同步方法,至少在promises could be used directly in .evaluate()
之前.
在可用之前,您可以使用.action()来模仿您想要的行为:
var Nightmare = require('nightmare');
Nightmare.action('deferredWait', function(done) {
var attempt = 0;
var self = this;
function doEval() {
self.evaluate_now(function(selector) {
return (document.querySelector(selector) !== null);
}, function(result) {
if (result) {
done(null, true);
} else {
attempt++;
if (attempt < 10) {
setTimeout(doEval, 2000); //This seems iffy.
} else {
done(null, false);
}
}
}, '#elem');
};
doEval();
return this;
});
var nightmare = Nightmare();
nightmare.goto('http://example.com')
.deferredWait()
.then(function(result) {
console.log(result);
});
标签:javascript,node-js,nightmare,web-crawler 来源: https://codeday.me/bug/20191002/1841376.html