【问题标题】:How to set time interval between page scraping with Phantomjs如何使用 Phantomjs 设置页面抓取之间的时间间隔
【发布时间】:2015-12-08 12:50:31
【问题描述】:

目前我用 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 内发送一大块项目(其中 10-20 个),然后等待 1 - 2 分钟,然后再发送下一批项目,而不会使网站不堪重负。或者,如果有办法设置时间间隔以每 2-3 秒循环遍历数组中的每个项目。

【问题讨论】:

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


    【解决方案1】:

    问题是 PhantomJS 是异步的,但循环迭代不是。甚至在加载第一页之前执行所有迭代(在第一个 sn-p 中)。您实际上是在生成多个同时运行的此类进程。

    您可以使用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(),这将为每个请求创建一个单独的进程,但是上面的代码会更快。

    【讨论】:

    • 谢谢!这正是我所需要的!
    【解决方案2】:

    您在添加 setInterval 方法的第二个 sn-p 中有一些拼写错误:

    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);
    

    ph.exit(); 永远无法联系到,我不知道这是否会给您带来任何问题,但您可能想看看它。

    【讨论】:

    • 感谢指正!我在编辑时搞砸了。感谢您提及return 声明。现在我知道它会停止执行并退出函数。
    猜你喜欢
    • 1970-01-01
    • 2019-06-12
    • 2014-04-04
    • 2023-04-07
    • 2022-01-12
    • 1970-01-01
    • 2011-11-09
    • 1970-01-01
    • 2018-08-01
    相关资源
    最近更新 更多