我是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有时是相对的,因此请首先检查它是否是有效的网址

08-27 19:27