如何设置与Phantomjs页面抓取之间的时间间隔

时间:2015-09-11 21:18:47

标签: javascript node.js web-scraping phantomjs iteration

目前我用Phantomjs编写了一个脚本,可以浏览多个页面。我的脚本有效,但我无法弄清楚如何设置刮擦之间的时间间隔。我尝试使用setInterval并且每隔5秒钟从arrayList传递一些项目,但它似乎不起作用。我的剧本一直在破碎。这是我的示例phantomjs脚本代码:

没有setInterval

var arrayList = ['string1', 'string2', 'string3'....]

arrayList.forEach(function(eachItem) {
    var webAddress = "http://www.example.com/eachItem"    
    phantom.create(function(ph) {
    return ph.createPage(function(page) {

        return page.open(yelpAddress, function(status) {
            console.log("opened site? ", status);


            page.injectJs('http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js', function() {

                setTimeout(function() {
                    return page.evaluate(function() {

                        //code here for gathering data


                    }, function(result) {
                        return result
                        ph.exit();
                    });

                }, 5000);

            });
        });
    });
});

使用setInterval

var arrayList = ['string1', 'string2', 'string3'....]
var i = 0
var scrapeInterval = setInterval(function() {
    var webAddress = "http://www.example.com/arrayList[i]"    
    phantom.create(function(ph) {
    return ph.createPage(function(page) {

        return page.open(yelpAddress, function(status) {
            console.log("opened site? ", status);


              page.injectJs('http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js', function() {

                setTimeout(function() {
                    return page.evaluate(function() {

                           //code here for gathering data


                    }, function(result) {
                           return result
                           ph.exit();
                    });

                }, 5000);

            });
        });
    });
    i++
    if(i > arrayList.length) {
    clearInterval(scrapeInterval);        
}, 5000);

基本上,我想在arrayList内发送一大块itemss(10-20个)并等待1-2分钟并发送下一大块项目而不会压倒网站。或者,如果有办法设置一个时间间隔,每2-3秒循环一次数组内的每个项目。

2 个答案:

答案 0 :(得分:1)

问题是PhantomJS是异步的,但循环迭代却不是。即使在加载第一页之前,也会执行所有迭代(在第一个代码段中)。你实际上是在生成多个同时运行的进程。

您可以使用类似async的内容让它按顺序运行:

phantom.create(function(ph) {
    ph.createPage(function(page) {
        var arrayList = ['string1', 'string2', 'string3'....];

        var tasks = arrayList.map(function(eachItem) {
            return function(callback){
                var webAddress = "http://www.example.com/" + eachItem;
                page.open(webAddress, function(status) {
                    console.log("opened site? ", status);

                    page.injectJs('http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js', function() {

                        setTimeout(function() {
                            return page.evaluate(function() {
                                //code here for gathering data
                            }, function(result) {
                                callback(null, result);
                            });
                        }, 5000);
                    });
                });
            };
        });

        async.series(tasks, function(err, results){
            console.log("Finished");
            ph.exit();
        });
    });
});

当然,您也可以在每个任务中移动phantom.create(),这将为每个请求创建一个单独的流程,但上面的代码会更快。

答案 1 :(得分:0)

您在添加了setInterval方法的第二个代码段中有一些拼写错误:

var arrayList = ['string1', 'string2', 'string3'];
var i = 0;
var scrapeInterval = setInterval(function () {
    var webAddress = "http://www.example.com/arrayList[i]"
    phantom.create(function (ph) {
        return ph.createPage(function (page) {

            return page.open(yelpAddress, function (status) {
                console.log("opened site? ", status);


                page.injectJs('http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js', function () {

                    setTimeout(function () {
                        return page.evaluate(function () {
                            //code here for gathering data
                        }, function (result) {
                            return result
                            ph.exit();
                        });

                    }, 5000);

                });
            });
        });

        i++;
        if (i > arrayList.length) {
            clearInterval(scrapeInterval);
        } //This was missing;
    }); //This was missing;
}, 5000);

我注意到的是,以下超时中的return语句:

setTimeout(function () {
    return page.evaluate(function () {
        //code here for gathering data
    }, function (result) {
        return result
        ph.exit();
    });
}, 5000);
我永远无法联系到{p> ph.exit();,我不知道这是否会对您造成任何问题,但您可能需要查看它。