phantomjs没有将网页呈现为png

时间:2016-03-07 20:24:06

标签: javascript phantomjs

我的代码就是这样的几行

var a = "http://lnmtl.com/chapter/renegade-immortal-chapter-";
var b = 558;
var d = "rennegrade_ch";
var f = ".png";
var page = require('webpage').create();
var i = 0;
for (i = b; i < 560; i++) {
    var c = a + i;
    console.log(c);
    page.open(c, function () {
        var e = d + i + f;
        console.log(e);
        page.render(e);

    });
}
phantom.exit();

网页可以单独呈现,但是一旦我把它放在for循环中,它所做的就是正确打印第一个控制台输出但第二个它跳过我猜它没有进入page.open函数然后for循环值增加然后相同事情再次发生我不知道为什么它没有进入渲染功能我试图把var page = require('webpage')。create(); 内部循环,但仍然没有变化

更新:在另一个问题上stackoverflow.com/questions/31621577/png-is-not-being-rendered-using-phantomjs-with-multiple-attempts-in-a-loop?rq=1 有人指出这种方法不能正常工作,因为函数的异步性质,但它提供的示例代码是不够有用的任何人都可以,我也尝试设置超时,因为它仍然发生同样的事情,所以任何其他想法?

2 个答案:

答案 0 :(得分:1)

在进行任何渲染之前,您的phantom.exit()调用会杀死PhantomJS浏览器。您必须等到渲染结束才能exit()。你需要有一些机制来说明渲染完成的时间。我建议将每个渲染器包装在Promise中。然后使用Promise.all()等待所有渲染承诺解析。解决之后,退出PhantomJS。

目前,您拥有以下内容,但不尊重page.open()的异步性质:

for (...) {
    // I probably wont finish because phantom dies almost immediately
    page.open(c, function () {
        // I won't finish running since phantom dies
        page.render(e);
    });
}
// I'm going to kill the phantom almost immediately
phantom.exit();

你需要类似下面的代码,它将等待所有渲染完成。这将把我们提供的每个站点的渲染放在子目录“渲染”中。

注意:由于PhantomJS尚未支持Promises,因此您需要安装es6-promise垫片才能正常工作。感谢关于the comment

Artjon B
/*jslint node:true*/
/*globals phantom, sayHello*/

"use strict";

var Promise = require("es6-Promise").Promise;

// Array of URLs that we want to render
var urlArr = [
    {
        name: "google",
        url: "http://www.google.com"
    },
    {
        name: "yahoo",
        url: "http://www.yahoo.com"
    },
    {
        name: "bing",
        url: "http://www.bing.com"
    }
];

// Map URLs to promises
var proms = urlArr.map(function (url) {
    // Return a promise for each URL
    return new Promise(function (resolve, reject) {
        // Make a page
        var page = require("webpage").create();
        // Open the URL
        console.log("opening: " + url.name);
        page.open(url.url, function () {
            // Render the page
            page.render("render/" + url.name + ".png");
            console.log("done rendering: " + url.name);
            // Say that we are done with rendering
            resolve();
        });
    });
});

// Wait for all rendering to finish
Promise.all(proms).then(function () {
    console.log("closing phantom");
    // Exit phantom
    phantom.exit();
});

答案 1 :(得分:0)

对于循环内的异步请求,您应该使用异步库,这样您就可以调试代码并且不会出现内存泄漏问题

async-js在你的情况下会很好

npm install async

var async = require('async');
var a = "http://lnmtl.com/chapter/renegade-immortal-chapter-";
var b = 558;
var d = "rennegrade_ch";
var f = ".png";
var page = require('webpage').create();
var i = 0;
async.whilst(
  function() {
    return i < 560;
  },
  function(callback) {
    i++;
    var c = a + i;
    console.log(c);
    page.open(c, function() {
      var e = d + i + f;
      console.log(e);
      page.render(e);
      callback(null, i);
    });
  },
  function(err, n) {
    if(err) console.log(err);
    phantom.exit();
  });