2013-03-04 49 views
7

在我的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

回答

9

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

8

我和這篇文章的作者有同樣的問題,沒有任何代碼示例適用於我。 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

1

的根本原因是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

5

只是一個快速的幫助誰到這裏來尋找其中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 
     }); 

希望這樣可以節省別人的麻煩!

0

偷從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."); 
    } 
}); 
4

我不知道,如果事情發生了變化,但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文件位於同一目錄中。我試圖爲圖像文件指定一個完全合格的路徑,但似乎沒有工作。

0

在這裏有很多好的建議。我想添加的一件事:

我正在運行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