PhantomJS 是一個基於 WebKit 的服務器端 JavaScript API。它全面支持web而不需瀏覽器支持,其快速,原生支持各類Web標準: DOM 處理, CSS 選擇器, JSON, Canvas, 和 SVG。 PhantomJS 能夠用於 頁面自動化 , 網絡監測 , 網頁截屏 ,以及 無界面測試 等。javascript
安裝包下載地址: http://phantomjs.org/download.html ,包括 Windows ,Mac OS,Linux版本,自行選擇對應 版本下載解壓便可( 爲方便使用,可自已爲phantomjs設置環境變量 ),其中帶有一個example文件夾,裏面有不少已經寫好的代碼供使用。本文假設phantomjs已經安裝好並已設置了環境變量。php
新建一個包含下面兩行腳本的文本文件:html
console.log('Hello, world!'); phantom.exit();
將文件另存爲 hello.js
,而後執行它:java
phantomjs hello.js
輸出結果爲:Hello, world!jquery
第一行將會在終端打印出字符串,第二行 phantom.exit
將退出運行。
在該腳本中調用 phantom.exit
是很是重要的,不然 PhantomJS 將根本不會中止。git
Phantomjs如何傳遞參數呢?以下所示 :github
phantomjs examples/arguments.js foo bar baz
其中的foo, bar, baz就是要傳遞的參數,如何獲取呢:web
var system = require('system'); if (system.args.length === 1) { console.log('Try to pass some args when invoking this script!'); } else { system.args.forEach(function (arg, i) { console.log(i + ': ' + arg); }); } phantom.exit();
它將輸出 :ajax
0: foo 1: bar 2: baz
經過建立一個網頁對象,一個網頁能夠被加載,分析和渲染。sql
下面的腳本將示例頁面對象最簡單的用法,它加載 example.com 而且將它保存爲一張圖片, example.png
。
var page = require('webpage').create(); page.open('http://example.com', function () { page.render('example.png'); phantom.exit(); });
因爲它的這個特性,PhantomJS 能夠用來 網頁截屏 ,截取一些內容的快照,好比將網頁、SVG存成圖片,PDF等,這個功能很牛X。
接下來的 loadspeed.js
腳本加載一個特殊的URL (不要忘了http協議) 而且計量加載該頁面的時間。
var page = require('webpage').create(), system = require('system'), t, address; if (system.args.length === 1) { console.log('Usage: loadspeed.js <some URL>'); phantom.exit(); } t = Date.now(); address = system.args[1]; page.open(address, function (status) { if (status !== 'success') { console.log('FAIL to load the address'); } else { t = Date.now() - t; console.log('Loading time ' + t + ' msec'); } phantom.exit(); });
在命令行運行該腳本:
phantomjs loadspeed.js http://www.google.com
它輸出像下面的東西:
Loading http://www.google.com Loading time 719 msec
要想在網頁的上下文中對JavaScript 或 CoffeeScript 進行運算,使用 evaluate()
方法。代碼是在「沙箱」中運行的,它沒有辦法讀取在其所屬頁面上下文以外的任何JavaScript對象和變量。 evaluate()
會返回一個對象,然而它僅限制於簡單的對象而且不能包含方法或閉包。
這有一個示例來顯示網頁標題:
var page = require('webpage').create(); page.open(url, function (status) { var title = page.evaluate(function () { return document.title; }); console.log('Page title is ' + title); });
任何來自於網頁而且包括來自 evaluate()
內部代碼的控制檯信息,默認不會顯示的。要重寫這個行爲,使用 onConsoleMessage
回調函數,前一個示例能夠被改寫成:
var page = require('webpage').create(); page.onConsoleMessage = function (msg) { console.log('Page title is ' + msg); }; page.open(url, function (status) { page.evaluate(function () { console.log(document.title); }); });
因爲腳本好像是一個Web瀏覽器上運行的同樣,標準的DOM腳本和CSS選擇器能夠很好的工做。這使得PhantomJS適合支持各類 頁面自動化任務 。
下面的 useragent.js
將讀取 id 爲myagent的元素的 textContent
屬性:
var page = require('webpage').create(); console.log('The default user agent is ' + page.settings.userAgent); page.settings.userAgent = 'SpecialAgent'; page.open('http://www.httpuseragent.org', function (status) { if (status !== 'success') { console.log('Unable to access network'); } else { var ua = page.evaluate(function () { return document.getElementById('myagent').textContent; }); console.log(ua); } phantom.exit(); });
上面示例一樣提供了一種自定義 user agent
的方法。
使用JQuery及其餘類庫:
var page = require('webpage').create(); page.open('http://www.sample.com', function() { page.includeJs("http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js", function() { page.evaluate(function() { $("button").click(); }); phantom.exit() }); });
將一個頁面從一臺遠程服務器請求一個資源的時候,請求和響應都可以經過 onResourceRequested
和 onResourceReceived
回調方法追蹤到。示例 netlog.js :
var page = require('webpage').create(); page.onResourceRequested = function (request) { console.log('Request ' + JSON.stringify(request, undefined, 4)); }; page.onResourceReceived = function (response) { console.log('Receive ' + JSON.stringify(response, undefined, 4)); }; page.open(url);
獲取如何把該特性用於HAR 輸出以及基於YSlow的性能分析的更多信息,請參閱 網絡監控頁面 。
PhantomJs官網: http://phantomjs.org/
GitHub: https://github.com/ariya/phantomjs/wiki/Quick-Start
上述幫助說明,來源於woiweb:https://www.tuicool.com/articles/beeMNj
下面直接給出執行代碼:
echo '<meta charset = "utf-8">'; exec('H:\wamp\www\phantomjs\bin\phantomjs --output-encoding=utf8 H:\wamp\www\Xss_Scanner\test.js ',$output_main);</pre></li><li><pre>var_dump($output_main);
// $str = implode('',$output_main); // var_dump($str);</pre></li></ol><p class="article-p">test.js文件裏面的內容以下:</p><ol class="article-ol"><li><pre>console.log('Loading a web page');</pre></li><li><pre>var page = require('webpage').create();</pre></li><li><pre>var url = 'http://www.mafutian.net/';</pre></li><li><pre>page.open(url, function (status) {</pre></li><li><pre> //Page is loaded!</pre></li><li><pre> if (status !== 'success') {</pre></li><li><pre> console.log('Unable to post!');</pre></li><li><pre> } else {</pre></li><li><pre> console.log(page.content);</pre></li><li><pre> }</pre></li><li><pre> phantom.exit();</pre></li><li><pre>});</pre></li></ol><p class="article-p">執行結果以下圖所示:</p><img class="article-img" animate="0" src="/public/blog/home/style/images/article/267_1.jpg" alt="請輸入圖片名稱"><p class="article-p">注意,可以實現上面執行結果須要主要下面幾點:</p><p class="article-p">(1)不能開啓 PHP 的安全模式,即在 php.ini 中須要將 sql.safe_mode 設置爲 Off。(並重啓服務器,固然, php 自己默認就是不開啓安全模式的)</p><p class="article-p">(2)不管 phantomjs 是否加入到系統環境變量中,在 exec() 中都應該是絕對路徑的,如下執行是無效的:</p><ol class="article-ol"><li><pre>exec('phantomjs --output-encoding=utf8 H:\wamp\www\Xss_Scanner\test.js ',$output_main);
須要將 phantomjs 取絕對路徑。
須要注意的是 js 文件能夠不取絕對路徑。能夠是相對於網站根目錄的,下面執行是成功的:
exec('H:\wamp\www\phantomjs\bin\phantomjs --output-encoding=utf8 test.js ',$output_main);
注:test.js 放置於網站的根目錄下。
另外:在 PHP 下執行 phantomjs 也可使用另一個函數 systom() 來執行
以上內容參考:連接地址:http://www.mafutian.net/267.html
<?php require 'vendor/autoload.php'; use JonnyW\PhantomJs\Client;//引入客戶端 /*自定義模塊*/ use JonnyW\PhantomJs\DependencyInjection\ServiceContainer; $location = '/path/to/your/script/directory';//自定義模塊所在文件夾 $serviceContainer = ServiceContainer::getInstance(); $procedureLoader</span> = <span class="hljs-variable">$serviceContainer->get('procedure_loader_factory') ->createProcedureLoader($location);//詳細參見本文頁尾 /*正常實例*/ $client = Client::getInstance();//實例 /*自定義模塊*/ $client->setProcedure('my_procedure');//加載一個名爲my_procedure.proc的自定義js模塊,詳見本文頁尾 $client</span>->getProcedureLoader()->addLoader(<span class="hljs-variable">$procedureLoader);//自動加載模塊 /*自設phantomjs參數*/ $client->getEngine()->addOption('--load-images=true');//phantomjs參數,參數地址:http://phantomjs.org/api/command-line.html $client->getEngine()->addOption('--config=/path/to/config.json');//除了單獨配置命令,還可配置命令集配置的json文件::本文頁尾列舉了經常使用的配置 /*調試與緩存*/ $client->getEngine()->debug(true);//容許或禁止調試 $client->getLog(); //開啓調試則輸出結果 $client->getProcedureCompiler()->clearCache();//清除緩存.建議容許前進行清除 $client->getProcedureCompiler()->enableCache();//容許緩存,建議開啓 $client->getProcedureCompiler()->disableCache();//禁止讀取緩存 /*渲染與請求方式*/ $link='http://jonnnnyw.github.io/php-phantomjs/4.0/3-usage/#on-load-finished';//請求的url $client->isLazy(); // 是否讓客戶端等待全部資源加載完畢,開啓此項務必開始setTimeout,避免輪詢頁面不斷等待. $request</span> = <span class="hljs-variable">$client->getMessageFactory()->createRequest(); $response</span> = <span class="hljs-variable">$client->getMessageFactory()->createResponse(); $request</span>->setUrl(<span class="hljs-variable">$link); $request->setMethod('GET');//可GET|POST|OPTIONS|HEAD|DELETE|PATCH|PUT $request->setTimeout(5000);//超過指定時間則中斷渲染 $request->setDelay(5);//設置延遲5秒 $request->setRequestData(array('param1' => 'Param 1','param2' => 'Param 2'));//POST時發送的數據 $request->addHeader('custom_header_key', 'custom_header_value');//自定義頭信息 $client</span>->send(<span class="hljs-variable">$request, $response);//發送請求 /*截圖(圖或PDF文件)*/ $request->setRepeatingHeader('<h1>Header <span style="float:right">%pageNum% / %pageTotal%</span></h1>',100);//自定義PDF類的頭尾及其高度 $request->setRepeatingFooter('<footer>Footer <span style="float:right">%pageNum% / %pageTotal%</span></footer>',100);//自定義PDF類的頭尾 $request->setViewportSize(200, 100);//設置可視寬高 $request->setBodyStyles(array('backgroundColor' => '#ff0000'));//設置紙張背景色 $request->setFormat('A4');//設置尺寸格式,如A4 $request->setOrientation('landscape');//設置紙張方向如縱向 $request->setPaperSize('10cm', '20cm');//PDF紙張大小 $request->setMargin('1cm');//PDF紙張邊距 $request->setOutputFile('E:\php\file.jpg|file.pdf');//截圖或PDF存儲路徑 $request</span>->setCaptureDimensions(<span class="hljs-number">240</span>, <span class="hljs-number">320</span>, <span class="hljs-number">10</span>, <span class="hljs-number">20</span>);<span class="hljs-comment">//設置截圖寬高與邊距$width, $height, $top, $left /*響應結果*/ $response->getHeaders();//返回頭組成的數組 $response->getHeader();//返回頭 $response->getStatus();//返回狀態碼:200則正確,其他錯誤. $response->getContent();//返回正文 $response->getContentType();//返回正文類型 $response->getUrl();//返回請求地址 $response->getRedirectUrl();//返回重定向後的地址 $response->isRedirect();//返回是否重定向 $response->getConsole();//返回JS控制檯內容
A. 經常使用命令參數:
1.--ignore-ssl-errors=[true|false]
忽略SSL錯誤,例如過時或自簽名證書錯誤(默認爲false
)。
2.--load-images=[true|false]
加載全部內聯圖像(默認爲true
)。
其它的不多用獲得,http://phantomjs.org/api/command-line.html
B.自定義模塊用法:
global_variables.partial 容許任何javascript變量注入腳本的頂部。
page_clip_rect.partial 若是請求是屏幕捕獲,這將定義頁面裁剪矩形。
page_custom_headers.partial 在頁面對象上設置任何自定義標題。
page_on_error.partial 定義頁面錯誤執行的代碼。
page_on_resource_received.partial 定義在資源接收時執行的代碼。
page_on_resource_timeout.partial 定義在資源超時時執行的代碼。
page_open.partial 定義頁面打開時執行的代碼。
page_paper_size.partial 若是請求是PDF輸出,這將設置紙張尺寸。
page_settings.partial 最明顯地定義任何頁面設置資源超時值。
page_viewport_size.partial 若是在請求中定義,請設置視口大小。
page_body_styles.partial 在請求的頁面的body標籤上設置CSS樣式。
phantom_on_error.partial 定義在PhantomJS錯誤中執行的代碼。
procedure_capture.partial 定義請求是捕獲請求時執行的代碼。
procedure_default.partial 定義爲默認請求執行的代碼。
procedure_pdf.partial 定義請求是PDF請求時執行的代碼。
編譯的時候所對應的位置:https://github.com/jonnnnyw/php-phantomjs/blob/master/src/JonnyW/PhantomJs/Resources/procedures/http_default.proc
除了上方的默認模塊以外,你也能夠自定義一個js模塊
首先建立至少755權限的.proc文件,例如/my_procedure(名稱隨意,上面引入時無需後綴).proc
//.proc示例腳本 var page = require('webpage').create(); page.open ('{{ input.getUrl() }}', '{{ input.getMethod() }}', '{{ input.getBody() }}', function (status) { //你的js腳本 phantom.exit(1);//退出 }); ...
更多細節,詳見.http://jonnnnyw.github.io/php-phantomjs/4.0/4-custom-scripts/