use*_*ser 3 javascript web-crawler node.js nightmare
我正在尝试使用 Nightmare 抓取网页,但希望等待#someelem出现,前提是它确实存在。否则,我想让 Nightmare 继续前进。这如何使用.wait()?
我不能用.wait(ms)。Using.wait(selector)表示 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)
Run Code Online (Sandbox Code Playgroud)
因此,等待并再次尝试(达到阈值),如果未找到该元素,则继续前进。setTimeout 周围的代码似乎是错误的,因为.wait它是在浏览器范围内完成的。
提前致谢!
我不认为通过cheerio你拥有的图书馆会很好地工作。参数被序列化(或多或少)以传递给子电子进程,因此传递整个库可能不起作用。
从好的方面来说, 的fn部分.wait(fn)在页面上下文中执行 - 这意味着您可以完全访问document它及其拥有的方法(例如,querySelector)。如果存在,您还可以访问页面的 jQuery 上下文,如果不存在,您甚至可以使用.inject()它来注入它。
撇开这一点不谈,就.wait()(并且.evaluate(),就此而言)期望同步方法是正确的,至少在可以直接在.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);
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10682 次 |
| 最近记录: |