PhantomJS
直接从来浏览器中提取渲染好的HTMl文档。如果Ajax请求很多,有时请求参数还进行了加密,手工分析每一个Ajax请求,很麻烦。
这时候可以用PhantomJS直接提取浏览器渲染好的效果,不进行Ajax请求分析。
PhantomJS是一个基于WebKit的服务器端JavaScript API。全面支持Web而无需浏览器支持,原生支持各种Web标准:DOM处理,CSS选择器,JSON,Canvas和SVG。
PhantomJS可以用于页面自动化,网络检测,网页截图,以及无界面测试等。
PhantomJS可以看作一个没有界面的浏览器,既有Firefox浏览器,google浏览器的功能,又因为没有界面而更快,占更小内存。
Phantomjs
可以在 https://phantomjs.org/download.html 下载,直接解压然后配置一下环境变量。
快速入门
新建一个JavaScript文件hello.js
console.log('Hello world!')
phantom.exit()
然后在命令行中输入
phantomjs hello.js
输出内容为:Hello,world!.代码中的第一句是控制台输出 ‘Hello, world’,第二局是终止phantom的运行,不然程序会一直运行,不会停止。
页面加载
通过PhantomJS,一个网页可以被加载,分析和通过创建网页对象呈现。
打开一个博客为例 http://www.cnblogs.com/qiyeboy/ 并将页面进行截图保存
var page = require('webpage').create()
page.open('https://www.cnblogs.com/qiyeboy/', function (status){
console.log('Status: ' + status)
if (status === 'success'){
page.render('qiye.png')
}
phantom.exit()
})
代码解释:使用webpage模块创建一个page对象,然后通过page对象打开网址,如果请求状态为success,则通过render方法将当前页面保存为qiye.png图片。
除了打开网页截图之外,还可以对网页的开打进行测速,同时还能给JavaScript脚本传递参数的功能。
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('FALL to load the address');
}else {
t = Date.now() - t
console.log('Loading ' + system.args[1]);
console.log('Loading time ' + t + ' mesc');
}
phantom.exit();
})
控制台输出 phantomjs .\loadspeed.js http://www.cnblogs.com/qiyeboy/
代码解释:使用webpage模块创建一个page对象,使用system模块获取系统对象system,并声明了两个变量t和address,用来保存时间和传入参数。
如果传入参数的长度等于1,说明要加载的地址没有传入,进行提示并退出phantom。为什么要等于1,因为phantomjs loadspeed.js第一个参数是loadspeed.js。
接着获取当前时间,然后打开网页,获取加载完成后的时间,进行相减即可。
代码评估
为了评估网页中的JavaScript代码,可以利用evaluate。这个执行是 '沙盒式'的,不会去执行网页外的JavaScript代码。evaluate方法可以返回一个对象,
返回值仅限于对象,不能包含函数(或闭包)。如果使用evaluate方法获取 http://www.cnblogs.com/qiyeboy/页面的标题。
var url = 'https://www.cnblogs.com/qiyeboy/'
var page = require('webpage').create()
page.open(url, function (status){
var title = page.evaluate(function (){
return document.title
})
console.log('Page title is ' + title)
phantom.exit()
})
任何来自于网页包括来自evaluate()内部代码的控制台信息,默认不会显示。要覆盖次行为,使用onConsoleMessage回调方法,改动
var url = 'https://www.cnblogs.com/qiyeboy/'
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)
})
phantom.exit()
})
屏幕捕获
由于PhantomJS使用的是WebKit内核,一个真正布局和渲染引擎,可以捕捉一个页面的屏幕截图。也可以渲染页面上的元素,可以用于HTML和CSS的内容转换,还可用于SVG和画布。
可以将网页保存为Pnr格式,jpg,gif,pdf格式
转为pdf
var page = require('webpage').create()
page.open('https://www.cnblogs.com/qiyeboy/', function (status) {
console.log('Status: ' + status)
if (status === 'success'){
page.render('qiye.pdf')
}
phantom.exit()
})
PhantomJS不仅可以将页面转化为不同的文件格式,还可以对视图进行缩放和裁剪,主要用到page对象中两个非常重要的属性:viewportSize和clipRect。
viewportSize是视区的大小,其作用可以看作是将开发的浏览器窗口进行缩放。
clipRect是在这个视区中裁剪矩形的大小,需要四个参数,前两个是基准点,后两个参数是宽高。
var page = require('webpage').create()
page.viewportSize = {width: 1024, height: 768}
page.clipRect = {top: 0, left: 0, width: 512, height: 256}
page.open('https://www.cnblogs.com/qiyeboy/', function (status) {
console.log('Status: ' + status)
if (status === 'success'){
page.render('qiye02.png')
}
phantom.exit()
})
网络监控
PhantomJS允许检验网络流量,可以用来分析网络行为和性能,实现对网络的监听。向远程服务器发送请求时,可以使用OnResourceRequested和onResourceReceived两个方法
获取所有资源请求和响应
var page = require('webpage').create()
console.log('The default user agent is ' + page.settings.userAgent)
page.settings.userAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36'
page.open('http://www.mtime.com/', function (status) {
if (status !== 'success'){
console.log('Unable to access network')
}else {
var ua = page.evaluate(function () {
return document.getElementsByClassName('fothr').item(0).innerHTML
})
console.log(ua)
}
phantom.exit()
})
页面自动化
PhantomJS可以加载和处理一个网页,可以适用于自动化处理,PhantomJS中标准JavaScript的DOM操作和CSS选择器都是生效的
--operator
代码解释:首先创建page对象,接着将默认的User-Agent进行了修改,打开指定网页,当加载完成之后,执行DOM操作。
PhantomJS允许添加外部的JS库,比如下面的例子添加Jquery
var page = require('webpage').create()
page.open('http://www.sample.com', function () {
page.includeJs('https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js', function (){
page.evaluate(function (){
$("button").click()
})
phantom.exit()
})
})
常用模块和方法
phantom webpage system fs四个模块
phantom
主要讲其中五个方法。
方法原型 功能 例子
{Boolean} addCookie 添加一个Cookie信息到Cookie-Jar phantom.addCookie({'name':'Added-Cookie-Name', 'value':'Added-Cookie-Value', 'domain': '.google.com'})
{void} clearCookies() 删除Cookiejar中的所有Cookie信息 phantom.clearCookies()
{Boolean}deleteCookie(cookieName) 删除指定名称的Cookie信息 phantom.deleteCookie('Added-Cookie-Name')
{void}phantom.exit(returnValue) 以指定的返回值退出程序 if (somethingIsWrong){phantom.exit(1)}else{phantom.exit(0)}
{boolean}phantom.injectJs(filename) 注入外部的js文件 var wasSuccessful = phantom.injectJs('')
webpage
includeJs, open两个普通方法,onInitialized, onLoadFinished两个回调方法
includeJs方法原型为includeJs(url, callback),功能时从指定的url获取远程javaScript脚本,并执行回调方法
var webPage = require('webpage')
var page = webPage.create()
page.includeJs('xx.js', function() {
(page.evaluate(function() {
var $loginForm = $('from #login')
}))
})
open方法比较复杂,有四种函数重载方式,分别为 open(url, callback) open(url, method, callback) open(url, method, data, callback), open(url,settings, callback)
url为链接,method为GET或者POST请求,data为附加的数据,callback为回调函数,settings为对请求头和你内容的设置
onInitialized是回调方法,在webpage对象被创建之后,url被加载之前被调用,主要是用来操作一些全局变量
var webPage = require('webpage')
var page = webPage.create()
page.onInitialized = function(){
page.evaluate(function() {
document.addEventListener('DOMContentLoaded', function() {
console.log('DOM content has loaded.')
}, false)
})
}
onLoadFinished是回调方法,在页面加载完成之后调用,方法还有一个参数status.如果加载成功status为success,否则为fail。
webpage中open方法就是用这个方法作为回调函数。
system
该模块只有属性,没有方法
属性 含义
args 从命令行中输入的参数,是一个字符串列表
env 系统变量,是一个键值对列表
os 操作系统的信息
pid 当前执行PhantomJS的进程号
platform 平台名称,总是PhantomJS
fs
模块全程为File System 主要是对文件系统进行操作。该模块方法很多,这里主要列一部分
方法 功能
touch 创建一个空文件
exists 判断文件是否存在
read 读文件
write 写文件