【问题标题】:Serialize function with PhantomJS bridge使用 PhantomJS 桥接序列化函数
【发布时间】:2013-08-26 02:28:07
【问题描述】:

我有一个链接数组,它们使用链接参数来获取由 PhantomJS 抓取数据的函数。 如何序列化这个功能?这个 for 语句一次运行并行 3 个函数,我收到一个 事件错误

在这种情况下使用 async 是正确的,但是如何串联使用呢?运行函数的时间总是不同的,但是 async 应该如何理解它已经完成并从新 URL 开始?

var phantom = require('phantom')
  , async = require('async');

var urls = [
  'http://en.wikipedia.org/wiki/Main_Page',
  'http://es.wikipedia.org/wiki/Wikipedia:Portada',
  'http://de.wikipedia.org/wiki/Wikipedia:Hauptseite'
];

async.mapSeries(urls, getTitle, function(err, result){
    console.log(result);
})

function getTitle (link, callback) {
  phantom.create(function(ph) {
    return ph.createPage(function(page) {
      return page.open(link, function(status) {
        return page.evaluate((function() {
          return document.title;
        }), function(result) {
          callback(null, result);
          return ph.exit();
        });
      });
    });
  });
};

【问题讨论】:

  • 你的scrapedData 函数看起来不是很异步,如果它returns 结果...
  • 为什么需要连续运行抓取?您可以轻松地将它们并行化。
  • @Bergi 我添加了一个回调,请检查它们是否在正确的位置,因为它仍然不起作用。
  • 什么是scrapedData.bind(crapedData)? Afaik 仅通过 crapedData 函数就足够了
  • @khaljava 尝试创建 1 个 phantomjs 实例,然后打开许多页面。而不是ph.exit() 执行page.close() 并仅在所有页面都调用回调时退出。

标签: javascript node.js async.js


【解决方案1】:

我会尝试类似:

var links = []
var _ph

function init(cb) {
    phantom.create(function(ph) {
        //for each link in links call doStuff()
        _ph = ph 
        doStuff(ph, link, cb)   
    })   
}

function doStuff(ph, link, cb) {
    ph.createPage(function(page) { //does things in parallel?
      page.open(link, function(status) {
        page.evaluate((function() {
          document.title;
        }), function(result) {
          cb(null, result);
          page.close();
        });
    });
}

var counter = links.length
var titles;

function results(err, res) {
  titles.push(res)

  if(--counter == 0) {
    //done
    _ph.exit()
  }
 }

init(results)

可能无法正常工作的代码(我在这里写的),但我希望你能明白。如果您只想使用 1 页,例如:

var links = []
var _ph
var _page

function init(cb) {
    phantom.create(function(ph) {

        _ph = ph 
        ph.createPage(function(page) {
             _page = page
             doStuff(link, cb)
        }   
    })   
}

function doStuff(page, link, cb) {
      page.open(link, function(status) {
        page.evaluate((function() {
          document.title;
        }), function(result) {
          cb(null, result);
          page.close();
        });
    });
}

 var counter = links.length
var titles;

function results(err, res) {
  titles.push(res)

  if(--counter == 0) {
    //done
    _ph.exit()
    return
  }

  doStuff(links[counter], results)
 }

init(results)

【讨论】:

  • 好主意,但是当async 库已经可用时,你真的应该使用它:-)
  • @fusio 感谢您的回答,但对于您创建的 '_ph' 变量
猜你喜欢
  • 2013-05-31
  • 2018-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-12
  • 1970-01-01
  • 2012-01-08
  • 2014-03-19
相关资源
最近更新 更多