php结合phantomjs实现⽹页截屏、抓取js渲染的页⾯
⾸先PhantomJS快速⼊门
是⼀个基于 WebKit 的服务器端  API。它全⾯⽀持web⽽不需浏览器⽀持,其快速,原⽣⽀持各种Web标准: DOM 处理, CSS 选择器, JSON, Canvas, 和 SVG。 PhantomJS 可以⽤于,,,以及等。
⼀、安装
⼆、使⽤
Hello, World!
新建⼀个包含下⾯两⾏脚本的⽂本⽂件:
console.log('Hello, world!');
将⽂件另存为hello.js ,然后执⾏它:
phantomjs hello.js
输出结果为:Hello, world!
第⼀⾏将会在终端打印出字符串,第⼆⾏it将退出运⾏。
在该脚本中调⽤it是⾮常重要的,否则 PhantomJS 将根本不会停⽌。
脚本参数 – Script Arguments
Phantomjs如何传递参数呢?如下所⽰:
phantomjs examples/arguments.js foo bar baz
其中的foo, bar, baz就是要传递的参数,如何获取呢:
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);
});
}
它将输出:
0: foo
1: bar
2: baz
页⾯加载 – Page Loading
通过创建⼀个⽹页对象,⼀个⽹页可以被加载,分析和渲染。
下⾯的脚本将⽰例页⾯对象最简单的⽤法,它加载 example 并且将它保存为⼀张图⽚,example.png。
var page = require('webpage').create();
page.open('example', function () {
});
由于它的这个特性,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>');
}
t = w();
address = system.args[1];
page.open(address, function (status) {
if (status !== 'success') {
console.log('FAIL to load the address');
} else {
t = w() - t;
console.log('Loading time ' + t + ' msec');
}
});
在命令⾏运⾏该脚本:
phantomjs loadspeed.js le
它输出像下⾯的东西:
代码运算 – Code Evaluation
要想在⽹页的上下⽂中对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();
javascript的特性
console.log('Page title is ' + msg);
};
page.open(url, function (status) {
page.evaluate(function () {
console.log(document.title);
});
});
DOM操作 – DOM Manipulation
由于脚本好像是⼀个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('', function (status) {
if (status !== 'success') {
console.log('Unable to access network');
} else {
var ua = page.evaluate(function () {
ElementById('myagent').textContent;
});
console.log(ua);
}
});
上⾯⽰例同样提供了⼀种⾃定义user agent的⽅法。
使⽤JQuery及其他类库:
var page = require('webpage').create();
page.open('www.sample', function() {
page.includeJs("leapis/ajax/libs/jquery/1.6.1/jquery.min.js", function() {
page.evaluate(function() {
$("button").click();
});
});
});
⽹络请求及响应 – Network Requests and Responses
将⼀个页⾯从⼀台远程服务器请求⼀个资源的时候,请求和响应均可以通过onResourceRequested和onResourceReceived回调⽅法追踪到。⽰例:
var page = require('webpage').create();
console.log('Request ' + JSON.stringify(request, undefined, 4));
};
console.log('Receive ' + JSON.stringify(response, undefined, 4));
};
page.open(url);
获取如何把该特性⽤于HAR 输出以及基于YSlow的性能分析的更多信息,请参阅。
使⽤ windows下PHP 执⾏ phantomjs
下⾯直接给出执⾏代码:
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 = 需要将 phantomjs 取绝对路径。
需要注意的是 js ⽂件可以不取绝对路径。可以是相对于⽹站根⽬录的,下⾯执⾏是成功的:
exec('H:\wamp\www\phantomjs\bin\phantomjs --output-encoding=utf8 test.js ',$output_main);
注:test.js 放置于⽹站的根⽬录下。
另外:在 PHP 下执⾏ phantomjs 也可以使⽤另外⼀个函数 systom() 来执⾏
php-phantomjs中⽂API整理的集合DEMO
<?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参数,参数地址:/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='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 >%pageNum% / %pageTotal%</span></h1>',100);//⾃定义PDF类的头尾及其⾼度
$request->setRepeatingFooter('<footer>Footer <span >%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="hlj
s-number">320</span>, <span class="hljs-number">10</span>, <span class="hljs-number">20</span>);<span class="hljs-comment"> /*响应结果*/
$response->getHeaders();//返回头组成的数组
$response->getHeader();//返回头
$response->getStatus();//返回状态码:200则正确,其余错误.
$response->getContent();//返回正⽂
$response->getContentType();//返回正⽂类型
$response->getUrl();//返回请求地址
$response->getRedirectUrl();//返回重定向后的地址
$response->isRedirect();//返回是否重定向
$response->getConsole();//返回JS控制台内容
除了上⽅的默认模块之外,你也可以⾃定义⼀个js模块
⾸先创建⾄少755权限的.proc⽂件,例如/my_procedure(名称随意,上⾯引⼊时⽆需后缀).proc
//.proc⽰例脚本
var page  = require('webpage').create();
page.open ('{{ Url() }}', '{{ Method() }}', '{{ Body() }}', function (status) {
//你的js脚本
});
...

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。