我是PhantomJS的新手。我想加载一个页面,抓取其链接,然后依次打开每个链接,一次打开一个,甚至在每个请求之间都存在延迟。我很难让一个接一个地被解雇,所以我想也许我可以使用promise解决这个问题,但是我不认为Node库可以与Phantom一起使用。到目前为止,我所看到的每个示例都打开一个页面,然后退出。
这是我得到的:
var page = require('webpage').create();
page.open('http://example.com/secretpage', function(status) {
console.log(status);
if(status !== 'success') {
console.log('Unable to access network');
} else {
var links = page.evaluate(function() {
var nodes = [];
var matches = document.querySelectorAll('.profile > a');
for(var i = 0; i < matches.length; ++i) {
nodes.push(matches[i].href);
}
return nodes;
});
links.forEach(function(link) {
console.log(link);
page.open(link, function(status) { // <---- tries opening every page at once
console.log(status);
var name = page.evaluate(function() {
return document.getElementById('username').innerHTML;
});
console.log(name);
page.render('profiles/'+name + '.png');
});
});
}
// phantom.exit();
});
有没有一种方法可以按顺序打开每个链接?
最佳答案
对于这种典型情况,我使用async.js,尤其是队列component。
这是一个非常基本的实现
phantom.injectJs('async.js');
var q = async.queue(function (task, callback) {
page.open(task.url, function(status) { // <---- tries opening every page at once
if(status !== 'success') {
console.log('Unable to open url > '+task.url);
} else {
console.log('opened '+task.url);
//do whatever you want here ...
page.render(Date.now() + '.png');
}
callback();
});
}, 1);
// assign a callback
q.drain = function() {
console.log('all urls have been processed');
phantom.exit();
}
var page = require('webpage').create();
page.open('http://phantomjs.org/', function(status) {
console.log(status);
if(status !== 'success') {
console.log('Unable to access network');
} else {
var links = page.evaluate(function() {
var nodes = [];
var matches = document.querySelectorAll('a');
for(var i = 0; i < matches.length; ++i) {
nodes.push(matches[i].href);
}
return nodes;
});
links.forEach(function(link) {
q.push({url: link}, function (err) {
console.log('finished processing '+link);
});
});
}
});
Urls将添加到队列中,并将被并行处理(直到并发限制,此处为一个)。我重用了相同的页面实例,但这不是强制性的。
就像我过去曾经做过这种爬虫一样,让我再给您两个建议:
不要加载图像以加快测试速度
href有时是相对的,因此请首先检查它是否是有效的网址