如何循环链接并为 PhantomJS 中的每个站点执行 jQuery javascript

How to loop through links and execute a jQuery javascript for each site in PhantomJS

我正在尝试构建响应式网页设计测试工具。我设法在不同设备特定视口大小的 link 数组中捕获了每个 link。

但该工具的额外要求是能够将自定义 javascript 注入网站,等待该脚本完成,然后捕获页面状态(例如有人想打开 bootstrap 模式之前捕获它)。

到目前为止,我一直在使用 jQueryGo 节点模块来完成我的工作。

到目前为止我所取得的成就

我设法让它工作,但无法使用 jQuery 组件(我尝试使用 phantom 提供的 injectJs 和 includeJs)。在以下代码中使用 asyncjs 和一些辅助函数。

var $ = require('../node_modules/jquerygo/lib/jquery.go.js');
var async = require('../node_modules/jquerygo/node_modules/async/lib/async.js');

var jqueryCdn = 'http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js';
var links = [{
    url: "http://google.com",
    sitename: "Google",
    jsinject: function() {
      var log = document.querySelectorAll('title')[0].innerText;
      console.log(log);
    }
  },
  ...
];

var sizes = [{
    device: "desktop",
    userAgent: "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.120 Safari/537.36",
    width: 1440,
    height: 1080
  },
  ...

];

/*
 * This function wraps WebPage.evaluate, and offers the possibility to pass
 * parameters into the webpage function. The PhantomJS issue is here:
 *
 */
var evaluate = function(page, func) {
  var args = [].slice.call(arguments, 2);
  var fn = "function() { return (" + func.toString() + ").apply(this, " + JSON.stringify(args) + ");}";
  return page.evaluate(fn);
};

var adjustPageSettings = function(page, size) {
  page.set(
    'viewportSize', {
      width: size.width,
      height: size.height
    }
  );
  $.config.userAgent = size.userAgent;
  return page;
};

$.getPage(function(page) {
  /**
   * snaps screenshot of page and safes it
   * @param siteName
   * @param device
   * @param done
   */
  var snapShoot = function(siteName, device, done) {
    console.log('snapshooting: ' + siteName + ' for ' + device);
    page.render('screenshot' + siteName + device + '.png', done);
  };
  async.eachSeries(sizes, function(size, done) {
    async.eachSeries(links, function(link, done) {
      page = adjustPageSettings(page, size);
      page.open(link.url, function(status) {
        if (status == 'success') {
          async.series([
            function(done) {
              if (typeof link.jsinject == 'function') {
                evaluate(page, link.jsinject, '');
                done();
              } else {
                done();
              }
            },
            function(done) {
              snapShoot(link.sitename, size.device, done);
            }
          ], function() {
            done()
          });
        } else {
          console.log('couldnt load:' + link.url);
        }
      });
    }, done);
  });
});

但是一旦我使用 jQuery 组件如下:

...
$.getPage(function (page) {
    page.injectJs(jqueryCdn);
....

和...

var links = [
    {
        url: "http://google.com",
        sitename: "Google",
        jsinject: function () {
             var log = $('title').text();
             console.log(log);
          }
},

我收到 jQuery 未加载错误:

  phantom stdout: ReferenceError: Can't find variable: $
  phantomjs://webpage.evaluate():2
  phantomjs://webpage.evaluate():4
  phantomjs://webpage.evaluate():4
  phantomjs://webpage.evaluate():4

错误消息说 jQuery 没有加载到 DOM。

变量名jqueryCdn建议您使用远程资源(URL)。 page.injectJs() supports only local paths. You need to use page.includeJs()。不要忘记使用回调,否则可能会执行您的脚本,但 jQuery 尚未加载到 DOM.