phantom.js的屏幕截图保存在哪里?

问题描述:

在我的Mac上通过Homebrew安装后,刚开始使用Phantom.js。phantom.js的屏幕截图保存在哪里?

我想出来的例子通过https://github.com/ariya/phantomjs/wiki/Quick-Start

var page = require('webpage').create(); 
page.open('http://google.com', function() { 
    page.render('google.png'); 
    phantom.exit(); 
}); 

保存的网站截图,但我没有看到任何地方的图像。他们会和.js文件在同一个目录下吗?

+0

获得写入权限? – user123444555621 2013-03-04 21:14:07

+0

我如何确定? – 2013-09-23 15:20:32

PhantomJS通常会将图像渲染到与您正在运行的脚本相同的目录。所以是的,它应该与您使用PhantomJS运行的JavaScript文件位于同一个目录中。

EDIT

似乎该特定例子是有缺陷的。问题是page.render(...);需要一些时间来渲染页面,但在渲染完成之前您要调用phantom.exit()。我能够这样做是为了获得预期的输出:

var page = require('webpage').create(); 
page.open('http://google.com', function() { 
    page.render('google.png'); 
    setTimeout(function() { phantom.exit(); }, 5000) // wait five seconds and then exit; 
}); 

可惜,这是不理想的,所以我能拿出的东西,这是一个发好。我说“头发”,因为我基本上轮询时看到的页面呈现完毕:

var done = false; //flag that tells us if we're done rendering 

var page = require('webpage').create(); 
page.open('http://google.com', function (status) { 
    //If the page loaded successfully... 
    if(status === "success") { 
     //Render the page 
     page.render('google.png'); 
     console.log("Site rendered..."); 

     //Set the flag to true 
     done = true; 
    } 
}); 

//Start polling every 100ms to see if we are done 
var intervalId = setInterval(function() { 
    if(done) { 
     //If we are done, let's say so and exit. 
     console.log("Done."); 
     phantom.exit(); 
    } else { 
     //If we're not done we're just going to say that we're polling 
     console.log("Polling..."); 
    } 
}, 100); 

上面的代码工作,因为回调不立即执行。因此,轮询代码将启动并开始轮询。然后当执行回调时,我们检查页面的状态(如果我们能够成功加载页面,我们只想渲染)。然后我们呈现页面并将我们的轮询代码正在检查的标志设置为true。所以下次轮询代码运行时,标志是true,所以我们退出。

这看起来与PhantomJS运行webpage#render(...)调用的方式有关。我怀疑这是一个非阻塞呼叫,但根据作者this issue,这是一个阻塞呼叫。如果我不得不冒险猜测,渲染行为可能是阻塞调用,但渲染代码可能会将数据交给另一个线程处理,这会将数据保存到磁盘(因此这部分可能不是 - 阻止呼叫)。不幸的是,当执行回到主脚本并执行phantom.exit()时,这个调用可能仍在执行,这意味着前面提到的异步代码从来没有机会完成它正在做的事情。

我能够在PhantomJS论坛上找到一篇关于what you're describing的帖子。我看不到任何已提交的问题,所以如果您希望可以继续并发布一个问题。

+0

任何想法可能是错的? – 2013-03-04 17:46:54

+0

你可以发布你的代码吗?然后,我们应该能够看到发生了什么。 – 2013-03-04 19:58:35

+0

这是直接复制粘贴的例子在这里:https://github.com/ariya/phantomjs/wiki/Quick-Start – 2013-03-04 21:03:07

我和这篇文章的作者有同样的问题,没有任何代码示例适用于我。 Phantom.js文档中的第二个示例无法正常工作。在雪豹上使用Home Brew安装。

我发现了一个working example

var page = require("webpage").create(); 
var homePage = "http://www.google.com/"; 
page.settings.javascriptEnabled = false; 
page.settings.loadImages = false; 
page.open(homePage); 
page.onLoadFinished = function(status) { 
    var url = page.url; 
    console.log("Status: " + status); 
    console.log("Loaded: " + url); 
    page.render("google.png"); 
    phantom.exit(); 
}; 
+2

我会在调用'open()'之前设置'onLoadFinished'回调*,以保证安全。 :) – 2013-03-26 23:40:27

+1

我认为仍然存在退出可能发生在完成渲染之前的问题,所以这对我不起作用,但如果将它与上面的解决方案结合使用,并将其放入setTimeout函数中,它将起作用。所以感觉就像有两个问题。 1)等到页面在渲染之前加载并且2)在退出之前等待渲染完成。这是否有意义(新手与幻影)? – Ian 2015-03-31 15:50:02

的根本原因是page.render()可能不准备即使在onLoadFinished()事件来呈现图像。在page.render()可能成功之前,您可能需要等待几秒钟。我发现在PhantomJS中渲染图像的唯一可靠方法是反复调用page.render(),直到该方法返回true,表示它已成功呈现图像。

解决方案:

var page = require("webpage").create(); 
var homePage = "http://www.google.com/"; 

page.onLoadFinished = function(status) { 
    var rendered, started = Date.now(), TIMEOUT = 30 * 1000; // 30 seconds 
    while(!((rendered = page.render('google.png')) || Date.now() - started > TIMEOUT)); 
    if (!rendered) console.log("ERROR: Timed out waiting to render image.") 
    phantom.exit(); 
}; 

page.open(homePage); 
+0

有趣的是,'render'的retun类型记录为'{void}'。我实际上没有遇到渲染问题。也许这是由于旧版本或我在Windows和Linux上的事实。 – 2014-11-26 20:42:31

+0

您可以在它工作之前计算它失败了多少次? – 2014-11-26 20:43:57

只是一个快速的帮助谁到这里来寻找其中PhantomJS或CasperJS的屏幕截图保存的目录人:这是在默认脚本目录。但是,你确实有控制权。

如果你想控制他们保存你可以改变像这样的文件名:

page.render('screenshots/google.jpg'); // saves to scriptLocation/screenshots/ 
page.render('/opt/google.jpg'); // saves to /screenshots (in the root) 

或者,如果你使用CasperJS你可以使用:

casper.capture('/opt/google.jpg', 
     undefined, 
     { // imgOptions 
      format: 'jpg', 
      quality: 25 
     }); 

希望这样可以节省别人的麻烦!

偷从rasterize.js example,它比我接受的答案更可靠。

var page = require('webpage').create(); 

page.open('http://localhost/TestForTest/', function (status) { 
    console.log("starting..."); 
    console.log("Status: " + status); 

    if (status === "success") { 
     window.setTimeout(function() { 
      page.render('myExample.png'); 
      phantom.exit(); 
     }, 200); 
    } else { 
     console.log("failed for some reason."); 
    } 
}); 

我不知道,如果事情发生了变化,但http://phantomjs.org/screen-capture.html的例子对我来说工作得很好:

var page = require('webpage').create(); 
page.open('http://github.com/', function() { 
    page.render('github.png'); 
    phantom.exit(); 
}); 

我正在phantomjs-2.1.1-窗口。

但是,是什么导致我这个线程是最初的图像文件永远不会在我的磁盘上创建就像原来的问题。我认为这是某种安全问题,所以我登录到一个虚拟机,并开始将所有内容放在同一个目录中。我正在使用一个批处理文件来启动phantomjs.exe,并将.js文件作为参数传入。将所有文件都放在我的虚拟机上的同一个目录下,效果很好。通过试验和错误,我发现我的批处理文件必须与我的.js文件位于同一个目录中。现在,我的主机也一切正常。

所以总之...这可能是一个安全相关的问题。不需要添加任何类型的超时。

我对原始问题的回答是:如果您的所有设置都正确,那么该文件将与phantomjs.exe运行的.js文件位于同一目录中。我试图为图像文件指定一个完全合格的路径,但似乎没有工作。

在这里有很多好的建议。我想添加的一件事:

我正在运行phantomjs docker镜像,默认用户是“phantomjs”,而不是root。因此,我试图写,我并没有权限上(这是泊坞窗主机上的PWD)的位置...

> docker run -i -t -v $(pwd):/pwd --rm wernight/phantomjs touch /pwd/foo.txt 
touch: cannot touch '/pwd/foo.txt': Permission denied 

没有错误都运行上面的代码(一个或多个),但如果他们没有权限写入到目标,然后他们会默默地忽略的请求......

因此,例如,以@ vivin-paliath的代码(目前接受的答案):

var done = false; //flag that tells us if we're done rendering 

var page = require('webpage').create(); 
page.open('http://google.com', function (status) { 
    //If the page loaded successfully... 
    if(status === "success") { 
     //Render the page 
     page.render('google.png'); 
     console.log("Site rendered..."); 

     //Set the flag to true 
     done = true; 
    } 
}); 

//Start polling every 100ms to see if we are done 
var intervalId = setInterval(function() { 
    if(done) { 
     //If we are done, let's say so and exit. 
     console.log("Done."); 
     phantom.exit(); 
    } else { 
     //If we're not done we're just going to say that we're polling 
     console.log("Polling..."); 
    } 
}, 100); 

而且将其作为默认用户生成:

docker run -i -t -v $(pwd):/pwd -w /pwd --rm wernight/phantomjs phantomjs google.js 
Polling... 
Polling... 
Polling... 
Polling... 
Polling... 
Polling... 
Polling... 
Polling... 
Polling... 
Polling... 
Polling... 
Polling... 
Site rendered... 
Done. 

但是没有google.png并且没有错误。简单地将-u root添加到docker命令解决了这个问题,我在我的CWD中获得了google.png

为了完整性,最后的命令:

搬运工运行-u根-i -t -v $(PWD):/密码-w /密码--rm wernight/phantomjs phantomjs google.js