PhantomJS - 快速指南
PhantomJS - 概述
PhantomJS 被称为 无头浏览器,因为在执行 JavaScript 代码时无需浏览器参与。执行不会在浏览器显示中看到,而是在命令行提示符中看到。CSS 处理、DOM 操作、JSON、Ajax、Canvas、SVG 等功能都将在命令提示符中处理。PhantomJS 没有 GUI,因此,它的所有执行都在命令行中进行。
使用 PhantomJS,我们可以写入文件、读取文件内容或上传文件、进行屏幕截图、将网页转换为 pdf 等等。使用无头浏览器,您可以获得所有浏览器行为,即Cookies、Http 请求方法,即GET /POST、清除 Cookies、删除 Cookies等,重新加载页面,导航到其他页面。
PhantomJS 使用 WebKit,它具有与著名浏览器(Google Chrome、Mozilla Firefox、Safari 等)类似的浏览环境。它还提供了许多 JavaScript API,可帮助截取屏幕截图、上传文件、写入文件、读取文件、与网页交互等。
PhantomJS 不支持 Flash 或视频,因为它需要插件,并且很难在命令行上支持它们。
PhantomJS 的功能
现在让我们了解 PhantomJS 提供的功能。
页面自动化
PhantomJS 允许您在其 API 的帮助下读取页面内容。它可以帮助操作 DOM,使用外部库执行所需的任务。
屏幕截图
PhantomJS 有助于对指定页面进行屏幕截图,并将其保存为 PNG、JPEG、PDF 和 GIF 等各种格式的图像。借助屏幕截图,它可以轻松帮助确保 Web 内容正常。
PhantomJS 提供属性和方法,借助这些属性和方法,开发人员可以调整屏幕截图的大小并指定他们想要捕获的区域。
无头测试
PhantomJS 帮助在命令行上测试 UI。同时,借助屏幕截图,它可以轻松帮助查找 UI 中的错误。PhantomJS 有时无法单独帮助测试。但是,它可以与其他测试库(如 Mocha、Yoeman 等)一起打包。您可以借助 PhantomJS 上传文件并提交表单。
PhantomJS 可用于测试跨站点的登录,并确保安全性不受损害。PhantomJS 可以与其他工具(如 CasperJS、Mocha、Qunit)一起使用,以使测试更加强大。
网络监控
PhantomJS 的重要功能之一是使用可用的 API 监控网络连接。PhantomJS 允许检查网络流量;它适合对网络行为和性能进行各种分析。
PhantomJS 可用于在实时环境中收集有关网页性能的数据。PhantomJS 可以与 Yslow 等工具一起使用,以收集任何网站的性能指标。
PhantomJS - 环境设置
PhantomJS 是一款免费软件,根据 BSD 许可证 分发。它易于安装,并提供多种功能来执行脚本。PhantomJS 可在 Windows、Linux 和 Mac 等多个平台上轻松运行。
要下载 PhantomJS,您可以访问 - http://phantomjs.org/,然后单击下载选项。
适用于 Windows
下载页面显示不同操作系统的下载选项。下载 zip 文件,解压后您将获得可执行文件 phantom.exe。将 PATH 环境变量设置为 phantom.exe 文件的路径。打开新的命令提示符并输入 phantomjs –v。它应该会为您提供正在运行的 PhantomJS 的当前版本。
对于 MAC OS X
下载适用于 MAC OS 的 PhantomJS zip 文件并提取内容。下载内容后,将 PhantomJS 移动到 - /usr/local/bin/。在终端执行 PhantomJS 命令,即 phantomjs –v,它应该会为您提供 PhantomJS 的版本描述。
Linux 64 位
下载适用于 Linux 64 位的 PhantomJS zip 文件并提取内容。下载内容后,将 PhantomJS 文件夹移动到 /usr/local/share/ 并 创建符号链接 −
sudo mv $PHANTOM_JS /usr/local/share sudo ln -sf /usr/local/share/$PHANTOM_JS/bin/phantomjs /usr/local/bin。
在终端执行 phantomjs –v,它应该会给出 PhantomJS 的版本。
Linux 32 位
下载适用于 Linux 32 位的 PhantomJS zip 文件并提取内容。下载内容后,将 PhantomJS 文件夹移动到 /usr/local/share/ 并创建符号链接 −
sudo mv $PHANTOM_JS /usr/local/share sudo ln -sf /usr/local/share/$PHANTOM_JS/bin/phantomjs /usr/local/bin。
在终端执行 phantomjs –v,它应该会给出 PhantomJS 的版本。
也可以通过单击以下链接从 git 存储库中获取 PhantomJS 源代码 - https://github.com/ariya/phantomjs/
要在 PhantomJS 中运行脚本,命令如下 −
phantomjs jsfile arg1 arg2…
PhantomJS - Object
在本章中,我们将介绍 PhantomJS 的四个重要对象。它们如下所示 −
- CookiesEnabled
- Cookies
- LibraryPath
- Version
现在让我们详细讨论一下这些对象。
cookiesEnabled
它指示是否启用了 cookie。如果启用,它将返回 true;否则返回 false。
语法
其语法如下 −
phantom.cookiesEnabled
示例
cookieenabled.js
phantom.addCookie ({
//使用 addcookie 属性添加 cookie
name: 'c1',
value: '1',
domain: 'localhost'
});
console.log("Cookie Enabled value is : "+phantom.cookiesEnabled);
phantom.exit();
输出
命令 − phantomjs cookieenabled.js
Cookie Enabled value is : true
Cookies
它有助于向域添加和设置 cookie。它返回一个对象,其中包含该域可用的所有 cookie。
语法
其语法如下 −
phantom.cookies;
示例
文件名:phantomcookie.js
phantom.addCookie ({
name: 'c1',
value: '1',
domain: 'localhost'
});
phantom.addCookie ({
name: 'c2',
value: '2',
domain: 'localhost'
});
phantom.addCookie ({
name: 'c3',
value: '3',
domain: 'localhost'
});
console.log(JSON.stringify(phantom.cookies));
phantom.exit();
输出
命令 − phantomjs phantomcookie.js
[{"domain":".localhost","httponly":false,"name":"c3","path":"/","secure":false, "
value":"3"},{"domain":".localhost","httponly":false,"name":"c2","path":"/","sec u
re":false,"value":"2"},{"domain":".localhost","httponly":false,"name":"c1","pat h
":"/","secure":false,"value":"1"}]
在上面的例子中,我们向 localhost 域添加了一些 cookie。然后我们使用 phantom.cookies 获取它。它使用 JSON stringify 方法将 JavaScript 对象转换为字符串,返回一个包含所有 cookie 的对象。您还可以使用 foreach 访问 cookie 的名称/值。
LibraryPath
PhantomJS libraryPath 存储 injectJS 方法要使用的脚本路径。
语法
其语法如下 −
phantom.libraryPath
示例
以下是查找版本的示例。
var webPage = require('webpage');
var page = webPage.create();
page.open('http://www.tutorialspoint.com/jquery', function(status) {
if (status === "success") {
page.includeJs('http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js ', function() {
if (page.injectJs('do.js')) {
// returnTitle 是从我们的 do.js 文件加载的一个函数 - 见下文
return returnTitle();
});
console.log(title);
phantom.exit();
}
}
});
window.returnTitle = function() {
return document.title;
};
上述程序生成以下输出。
Jquery Tutorial
Version
它给出正在运行的 PhantomJS 的版本,并在对象中返回详细信息。例如:{"major":2,"minor":1,"patch":1
语法
其语法如下 −
phantom.version
示例
以下是查找版本的示例。
var a = phantom.version; console.log(JSON.stringify(a)); console.log(a.major); console.log(a.minor); console.log(a.patch); phantom.exit();
上述程序生成以下输出。
{"major":2,"minor":1,"patch":1}
2
1
1
在上面的例子中,我们使用了 console.log 来打印版本。目前,我们正在运行版本 2。它返回包含上述代码块中显示的详细信息的对象。
PhantomJS - 方法
PhantomJS 是一个无需浏览器即可执行 JavaScript 的平台。为此,使用以下方法,这些方法有助于添加 Cookie、删除、清除、退出脚本、注入 JS 等。
我们将在本章中进一步讨论这些 PhantomJS 方法及其语法。类似的方法,即addcookie,injectjs存在于网页模块中,将在后续章节中讨论。
PhantomJS 公开了以下方法,可以帮助我们在没有浏览器的情况下执行 JavaScript −
- addCookie
- clearCookie
- deleteCookie
- Exit
- InjectJS
现在让我们通过示例详细了解这些方法。
addCookie
addcookie 方法用于添加 cookie 并存储在数据中。它类似于浏览器存储它的方式。它接受一个参数,该参数是一个具有 cookie 所有属性的对象,其语法如下所示 −
语法
其语法如下 −
phantom.addCookie ({
"name" : "cookie_name",
"value" : "cookie_value",
"domain" : "localhost"
});
name、value、domain 是必须添加到 addcookie 函数的属性。如果 cookie 对象中缺少任何此属性,此方法将失败。
name − 指定 cookie 的名称。
value − 指定要使用的 cookie 的值。
domain − 将应用 cookie 的域。
示例
以下是 addcookie 方法的示例。
var page = require('webpage').create(),url = 'http://localhost/tasks/a.html';
page.open(url, function(status) {
if (status === 'success') {
phantom.addCookie({ //添加名称 cookie1,其值为 1
name: 'cookie1',
value: '1',
domain: 'localhost'
});
phantom.addCookie({ // 添加值为 2 的 cookie2
name: 'cookie2',
value: '2',
domain: 'localhost'
});
phantom.addCookie({ // 添加值为 3 的 cookie3
name: 'cookie3',
value: '3',
domain: 'localhost'
});
console.log('Added 3 cookies');
console.log('Total cookies :'+phantom.cookies.length);
// 将输出添加到 url 的 cookie 总数。
} else {
console.error('Cannot open file');
phantom.exit(1);
}
});
示例
a.html
<html>
<head>
<title>Welcome to phantomjs test page</title>
</head>
<body>
<h1>This is a test page</h1>
<h1>This is a test page</h1>
<h1>This is a test page</h1>
<h1>This is a test page</h1>
<h1>This is a test page</h1>
<h1>This is a test page</h1>
<h1>This is a test page</h1>
<h1>This is a test page</h1>
<h1>This is a test page</h1>
</body>
</html>
上述程序生成以下输出。
Added 3 cookies Total cookies :3
代码注释一目了然。
clearCookies
此方法允许删除所有 cookie。
语法
其语法如下 −
phantom.clearCookies();
此概念的工作原理类似于通过在浏览器菜单中选择来删除浏览器 cookie。
示例
以下是 clearCookies 方法的示例。
var page = require('webpage').create(),url = 'http://localhost/tasks/a.html';
page.open(url, function(status) {
if (status === 'success') {
phantom.addCookie({ //添加名称 cookie1,其值为 1
name: 'cookie1',
value: '1',
domain: 'localhost'
});
phantom.addCookie({ // 添加值为 2 的 cookie2
name: 'cookie2',
value: '2',
domain: 'localhost'
});
phantom.addCookie({ // 添加值为 3 的 cookie3
name: 'cookie3',
value: '3',
domain: 'localhost'
});
console.log('Added 3 cookies');
console.log('Total cookies :'+phantom.cookies.length);
phantom.clearCookies();
console.log(
'After clearcookies method total cookies :' +phantom.cookies.length);
phantom.exit();
} else {
console.error('Cannot open file');
phantom.exit(1);
}
});
a.html
<html>
<head>
<title>Welcome to phantomjs test page</title>
</head>
<body>
<h1>This is a test page</h1>
<h1>This is a test page</h1>
<h1>This is a test page</h1>
<h1>This is a test page</h1>
<h1>This is a test page</h1>
<h1>This is a test page</h1>
<h1>This is a test page</h1>
<h1>This is a test page</h1>
<h1>This is a test page</h1>
</body>
</html>
上述程序生成以下输出。
Added 3 cookies Total cookies :3 After clearcookies method total cookies :0
deleteCookie
删除 CookieJar 中任何具有与 cookieName 匹配的"name"属性的 cookie。如果成功删除,它将返回 true;否则返回 false。
语法
其语法如下 −
phantom.deleteCookie(cookiename);
让我们借助示例了解 addcookie、clearcookies 和 deletecookie。
示例
以下是演示 deleteCookie 方法 − 用法的示例。
文件:cookie.js
var page = require('webpage').create(),url = 'http://localhost/tasks/a.html';
page.open(url, function(status) {
if (status === 'success') {
phantom.addCookie({ //添加名称 cookie1,其值为 1
name: 'cookie1',
value: '1',
domain: 'localhost'
});
phantom.addCookie({ // 添加值为 2 的 cookie2
name: 'cookie2',
value: '2',
domain: 'localhost'
});
phantom.addCookie({ // 添加值为 3 的 cookie3
name: 'cookie3',
value: '3',
domain: 'localhost'
});
console.log('Added 3 cookies');
console.log('Total cookies :'+phantom.cookies.length);
//将输出添加到 url 的 cookie 总数。
console.log("Deleting cookie2");
phantom.deleteCookie('cookie2');
console.log('Total cookies :'+phantom.cookies.length);
phantom.clearCookies();
console.log(
'After clearcookies method total cookies :' +phantom.cookies.length);
phantom.exit();
} else {
console.error('Cannot open file');
phantom.exit(1);
}
});
上述程序生成以下输出。
phantomjs cookie.js Added 3 cookies Total cookies :3 Deleting cookie2 Total cookies :2 After clearcookies method total cookies :0
Exit
phantom.exit 方法将退出它已启动的脚本。它退出程序并返回值。如果没有传递任何值,则返回 '0'。
语法
其语法如下 −
phantom.exit(value);
如果您未添加 phantom.exit,则命令行会假定执行仍在进行中且不会完成。
示例
让我们看一个例子来了解 exit 方法的用法。
console.log('Welcome to phantomJs'); // 输出 Welcome to phantomJS
var a = 1;
if (a === 1) {
console.log('Exit 1'); //outputs Exit 1
phantom.exit(); // Code exits.
} else {
console.log('Exit 2');
phantom.exit(1);
}
上述程序生成以下输出。
phantomjs exit.js
Welcome to phantomJs Exit 1
phantom.exit 之后的任何代码都不会执行,因为 phantom.exit 是结束脚本的方法。
injectJs
InjectJs 用于在 phantom 中添加 addtionaljs 文件。如果在当前 目录 librarypath 中找不到该文件,则 phantom 属性 (phantom.libraryPath) 将用作跟踪路径的附加位置。如果文件添加成功,则返回 true,否则,如果无法找到该文件,则返回 false 以防失败。
语法
其语法如下 −
phantom.injectJs(filename);
示例
让我们看下面的例子来了解injectJs的用法。
文件名:inject.js
console.log("Added file");
文件名:addfile.js
var addfile = injectionJs(inject.js); console.log(addfile); phantom.exit();
输出
命令 − C:\phantomjs\bin>phantomjs addfile.js
Added file // coming from inject.js true
在上面的例子中,addfile.js 使用injectJs调用文件inject.js。执行addfile.js时,inject.js中的console.log将显示在输出中。由于文件inject.js已成功添加,因此addfile变量也显示为true。
PhantomJS - Webpage 网页模块属性
PhantomJS 提供了相当多的属性和方法来帮助我们与网页内的内容进行交互。
require("webpage").create() 命令创建一个网页对象。我们将使用此对象在下面列出的属性和方法的帮助下操作网页。
var wpage = require("webpage").create();
下表列出了我们将要讨论的所有网页属性。
| S.No | 属性和描述 |
|---|---|
| 1 | canGoBack
如果导航历史记录中有上一页,则此属性返回 true;如果没有,则返回 false。 |
| 2 | canGoForward
如果导航历史记录中有下一页,则此属性返回 true;如果不是,则为 false。 |
| 3 | clipRect
clipRect 是一个具有 top、left、width 和 height 值的对象,用于在 render() 方法使用时捕获网页的图像。 |
| 4 | Content
此属性包含网页的内容。 |
| 5 | cookies
使用 cookies,您可以设置/获取 URL 上可用的 cookie。它还将为您提供 URL 上可用的 cookie 以及页面上设置的新 cookie。 |
| 6 | customHeaders
customHeaders 指定将针对页面发出的每个请求发送到服务器的其他 HTTP 请求标头。 |
| 7 | Event
它提供了事件的长列表,即修饰符、键详细信息。 |
| 8 | focusedFrameName
返回当前聚焦框架的名称。 |
| 9 | frameContent
此属性提供活动框架的内容。 |
| 10 | frameName
返回当前聚焦框架的名称。 |
| 11 | framePlainText
此属性还提供当前活动框架的内容,但仅提供没有任何 html 标签的内容。 |
| 12 | frameTitle
提供活动框架的标题。 |
| 13 | frameUrl
此属性将提供当前焦点框架的 url。 |
| 14 | framesCount
提供页面上存在的框架数量。 |
| 15 | framesName
提供框架名称数组。 |
| 16 | libraryPath
此属性具有路径,由page.inectJs 方法。 |
| 17 | navigationLocked
此属性定义是否允许页面导航。如果为 true,它将位于当前页面 URL 上,并且不允许单击页面转到下一页。 |
| 18 | offlineStoragePath
此属性提供使用 window.localStorage 存储数据的路径。可以使用命令行中的 --local-storage-path 更改路径。 |
| 19 | offlineStorageQuota
此属性定义您可以在 window.localStorage 中存储的最大数据量。该值为 5242880 字节,即 5MB。此值可以在命令行中使用以下命令覆盖 --localstorage-quota = size。 |
| 20 | ownsPages
如果网页打开的页面是网页的子页面,ownsPages 将返回 true 或 false。 |
| 21 | pagesWindowName
PagesWindowName 将提供使用 window.open 打开的窗口的名称 |
| 22 | pages
pages 属性将为您提供使用 window.open 在页面中打开的页面数组。如果页面在 URL 中关闭,则不会考虑您引用的页面。 |
| 23 | paperSize
此属性提供大小,即需要将网页转换为 pdf 格式时网页的尺寸。paperSize 包含对象中所需的尺寸。 |
| 24 | plaintext
此属性还提供当前活动框架的内容,但仅提供没有任何 html 标签的内容。 |
| 25 | scrollPosition
这包含指示滚动位置的对象。它提供左侧和顶部。 |
| 26 | settings
当使用 page.open 方法时,此属性将提供网页的设置。一旦页面加载,设置属性中的更改将不会产生任何影响。 |
| 27 | title
此属性将为您提供您正在阅读的页面的标题。 |
| 28 | url
此属性将提供页面 url。 |
| 29 | viewportSize
此属性允许更改窗口显示的大小。它包含宽度和高度,您可以根据需要读取或更改它们。 |
| 30 | windowName
提供窗口的名称。 |
| 31 | zoomFactor
此属性指定 render 和 renderBase64 方法的缩放因子。它有助于缩放页面并在需要时进行屏幕截图。 |
PhantomJS - Webpage 网页模块方法
Webpage 网页模块具有用于Cookie、框架、页面导航、重新加载、渲染和文件上传的方法。
以下是网页上可用的方法。
| S.No | 方法和描述 |
|---|---|
| 1 | addCookie()
addCookie 方法将 cookie 添加到指定页面。 |
| 2 | childFramesCount() |
| 3 | childFramesName() |
| 4 | clearCookies()
将删除指定页面的所有 cookie。 |
| 5 | close()
此方法用于关闭页面并释放使用的内存。一旦调用 close,任何网页方法或属性都将不起作用。 |
| 6 | currentFrameName()
根据 http://phantomjs.org,此方法已弃用。 |
| 7 | deleteCookie()
这将删除名称与给定页面网址的现有 cookie 列表匹配的 cookie。 |
| 8 | evaluateAsync()
在页面内异步评估给定函数,而不阻止当前执行。此函数有助于异步执行某些脚本。 |
| 9 | evaluateJavascript()
EvaluateJavaScript 有助于以字符串形式执行传递给它的函数。请注意,传递的字符串必须只是一个函数。 |
| 10 | evaluate()
Evaluate 将执行传递给它的函数。如果函数包含控制台消息,则不会直接显示在终端中。要显示任何控制台消息,您需要使用 onConsoleMessage 幻像回调。 |
| 11 | getPage()
这将为您提供与 getpage 中传递的窗口名称匹配的子页面。 |
| 12 | goBack()
如果导航未锁定,它会提供导航历史记录中的上一页。 |
| 13 | goForward()
如果导航未锁定,它会在导航历史记录中显示下一页。 |
| 14 | go()
此方法允许您浏览页面。 |
| 15 | includeJs()
Includejs 在页面上执行外部 JS 文件,并在完成后执行回调函数。 |
| 16 | injectJs()
InjectJs 将指定文件中的外部脚本包含到页面中。如果当前目录中没有该文件,则使用 libraryPath 对文件进行额外搜索。如果文件已注入,则返回 true,否则返回 false。 |
| 17 | openUrl()
OpenUrl 打开一个网页,和 PhantomJS 的 open 方法类似,OpenUrl 还有一些额外的参数,包括 httpConf、设置和回调函数。 |
| 18 | open()
Open 用于打开一个网页。 |
| 19 | release()
Release 会释放页面的内存堆使用量,调用 release 后不要再使用页面实例方法。此方法和 close 方法类似,已弃用。而是使用 wpage.close()。 |
| 20 | reload()
Reload 用于重新加载当前使用的页面。 |
| 21 | renderBase64()
此方法获取屏幕截图并以 base46 格式将图像作为字符串提供。Renderbase64 支持 PNG、JPEG 和 JPG 等格式。目前不支持 gif。您可以使用 clipRect 属性来定义图像捕获的部分。 |
| 22 | renderBuffer()
RenderBuffer 将网页捕获到图像缓冲区,可直接发送到服务器。支持的格式包括 PNG、GIF 和 JPEG。 |
| 23 | render()
Render 有助于获取图像缓冲区并按照指定的格式保存。 |
| 24 | sendEvent()
用于向网页发送事件。它们不是 dom 事件。这些事件中的每一个都是根据用户交互发送到网页的。 |
| 25 | setContent()
setcontent 将使用指定的内容更改指定 url 的页面内容。 |
| 26 | stop()
它有助于停止页面加载。 |
| 27 | switchToChildFrame()
不建议使用switchToFrame(); |
| 28 | switchToFocusedFrame()
选择焦点所在的帧。 |
| 29 | switchToFrame()
选择具有指定名称且为当前帧的子帧的帧。 |
| 30 | switchToMainFrame()
选择主框架,即根窗口。 |
| 31 | switchToParentFrame()
它采用当前子框架的父框架。 |
| 32 | uploadFile()
此方法用于处理使用 html 中的表单完成的文件上传。PhantomJS 没有直接使用表单执行此操作的方法,可以使用 uploadFile 方法实现相同的操作。它采用 html 标签选择器来选择文件位置和要复制到的目的地。 |
Webpage 网页模块事件/回调
下表描述了Webpage 网页模块可用的回调。
| S.No | 回调和说明 |
|---|---|
| 1 | onAlert()
当页面上有警报时,将调用此回调;回调接受一个字符串,但不返回任何内容。 |
| 2 | onCallback()
OnCallback 用于将值从网页传递到网页对象,它是使用 window.callPhantom() 方法完成的,该方法在内部调用 onCallback 函数。 |
| 3 | onClosing()
当使用 page.close() 方法或 window.close() 方法关闭窗口时,将调用此方法。 |
| 4 | onConfirm()
当页面上有使用 ok /cancel 调用的确认消息时,将调用此回调。 |
| 5 | onConsoleMessage()
当网页中使用控制台消息时,将使用此回调。 onConsoleMessage 方法采用 3 个参数。 |
| 6 | onError()
当出现 JavaScript 错误时,将调用此回调。 onError 的参数是 msg 和 stack trace,后者是一个数组。 |
| 7 | onFilePicker()
这用于上传文件,当用户想要上传文件时会调用回调。 |
| 8 | onInitialized()
在页面加载前调用此回调。 |
| 9 | onLoadFinished()
当打开的页面完全加载时,会调用此函数。它有一个参数,用于指示加载是成功还是失败。 |
| 10 | onLoadStarted()
页面开始加载时会调用此回调。 |
| 11 | onNavigationRequested()
此回调指示导航事件何时发生。 |
| 12 | onPageCreated()
此回调是当页面打开新的子窗口时调用。 |
| 13 | onPrompt()
当网页调用提示时,会调用此回调。它需要 2 个参数,消息和答案。返回值是一个字符串。 |
| 14 | onResourceError()
当网页无法上传文件时,会调用此回调。 |
| 15 | onResourceReceived()
当收到页面请求的资源时,会调用此回调。 |
| 16 | onResourceRequested()
此函数当页面请求资源时调用。 |
| 17 | onResourceTimeout()
当使用 settings.resourceTimeout 时,请求的资源超时,会调用此回调。 |
| 18 | onUrlChanged()
当使用导航更改当前 URL 时,会调用此回调。它有一个回调参数,即新的 URL targetUrl 字符串。 |
网页子进程模块
Phantomjs 子进程模块有助于与子进程交互,并使用 stdin /stdout/stderr 与它们通信。子进程可用于执行 打印、发送邮件 等任务,或 调用用其他语言编写的程序。要创建子进程模块,您需要引用。
例如 −
var process = require("child_process");
Spawn 方法
使用 spawn 子进程,您可以订阅其 stdout 和 stderr 流以实时获取数据。
语法
其语法如下 −
var spawn = require('child_process').spawn;
示例
让我们看一个 spawn 方法的示例。
var process = require("child_process")
var spawn = process.spawn
var child = spawn("cmd", ['/c', 'dir']);
child.stdout.on("data", function (data) {
console.log("spawnSTDOUT---VALUE:", JSON.stringify(data))
})
child.stderr.on("data", function (data) {
console.log("spawnSTDERR:", JSON.stringify(data))
})
child.on("exit", function (code) {
console.log("spawnEXIT:", code)
})
Output
上述程序生成以下输出。
spawnSTDOUT---VALUE: " Volume in drive C is OS " spawnSTDOUT---VALUE: " Volume Serial Number is 7682-9C1B Directory of C: \phantomjs\bin " spawnSTDOUT---VALUE: "20-05-2017 10:01 <DIR> . 20-05-2017 10:01 <DIR> .. 13-05-2017 20:48 12 a,txt.txt 07-05-2017 08:51 63 a.js 06-05-2017 16:32 120,232 a.pdf 13-05-2017 20:49 spawnEXIT: 0
PhantomJS - 文件系统模块属性
文件系统模块有许多 API 来处理文件和目录。您可以创建/写入和删除文件/目录。要开始使用文件系统模块,您必须引用 fs 模块。
var fs = require('fs');
文件系统模块有两个可用属性:Separator 和 Working Directory。让我们详细了解它们。
分隔符
它告诉您用于文件路径的分隔符。
- 对于 Windows:\
- 对于 Linux:/
语法
其语法如下 −
fs.seperator
示例
var fs = require('fs');
console.log(fs.seperator);
phantom.exit();
上述程序生成以下输出。
undefined
workingDirectory
工作目录是PhantomJS执行的目录。
语法
其语法如下 −
var fs = require('fs');
fs.workingDirectory;
示例
var fs = require('fs');
console.log(fs.workingDirectory);
phantom.exit();
上述程序生成以下输出。
C:/phantomjs/bin
PhantomJS - 文件系统模块方法
下表包含文件系统模块上可用的所有方法及其说明。
| S.No | 方法和描述 |
|---|---|
| 1 | absolute
此方法提供 PhantomJS 运行的绝对路径。 |
| 2 | changeWorkingDirectory
这允许您更改工作目录并返回 true,如果成功,否则返回 false。 |
| 3 | copyTree
copyTree 将目录从一个路径复制到另一个路径。第一个参数是源文件夹,第二个参数是目标文件夹。 |
| 4 | copy
此方法有助于将文件从一个位置复制到另一个位置。它需要两个参数。第一个参数是源文件,第二个参数是要复制的文件路径。如果源文件或目标文件不存在,它将抛出错误。 |
| 5 | exists
它检查系统中是否存在给定的文件路径。如果存在则返回 true,否则返回 false。 |
| 6 | isAbsolute
如果文件路径是绝对路径,则此方法返回 true;如果是相对路径,则返回 false。 |
| 7 | isDirectory
isDirectory 告知给定文件是否为目录。如果是目录,则返回 true,否则返回 false。如果给定路径不存在,则返回 false。 |
| 8 | isExecutable
此方法将告知给定文件是否可执行。如果可执行,则返回 true,否则返回 false。 |
| 9 | isFile
这详细说明了给定的文件路径是否为文件。如果是文件则返回 true,如果不是则返回 false。 |
| 10 | isLink
如果文件路径是符号链接则返回 true,否则返回 false。 |
| 11 | isReadable
检查给定的文件是否可读。如果是,则返回 true,否则返回 false。 |
| 12 | isWritable
它判断给定文件是否可写。如果是,则返回 true,否则返回 false。 |
| 13 | lastModified
提供对文件的最后修改的详细信息。它告诉文件最后修改的日期和时间。 |
| 14 | list
它提供目录中存在的所有文件。 |
| 15 | makeDirectory
创建一个新目录。 |
| 16 | makeTree
makeTree 创建所有必要的文件夹以便能够形成最终目录。如果创建成功则返回 true,否则返回 false。如果目录已经存在,它将返回 true。 |
| 17 | move
它将文件从一个路径移动到另一个路径。 |
| 18 | open
它用于打开文件。 |
| 19 | readLink
这将返回由符号链接(或Windows 上的快捷方式)。如果路径不是符号链接或快捷方式,它将返回一个空字符串。 |
| 20 | read
这将读取给定的文件。 |
| 21 | removeDirectory
这将删除给定的目录。 |
| 22 | removeTree
它将从给定的文件夹中删除所有文件和文件夹,并且最后删除文件夹本身。如果在执行此过程时出现任何错误,它将抛出错误 - "无法删除目录树 PATH"并挂起执行。 |
| 23 | remove
它删除给定的文件。 |
| 24 | size
它给出文件的大小。 |
| 25 | touch
它创建一个给定的文件。 |
| 26 | write
写入给定文件。 |
PhantomJS - 系统模块属性
在本章中,我们将讨论 PhantomJS 的各种系统模块属性。
args
PhantomJS 的系统模块具有不同的属性,有助于传递参数、了解执行的文件等。
args 属性基本上返回在命令行传递的参数。您还可以传递要读取的页面 URL。如果您想要存储屏幕截图 pdf 文件或上传文件,可以将详细信息传递到命令行,并使用 args 属性读取。
让我们找到传递到命令行的每个参数的长度和获取方法。
语法
其语法如下 −
var system = require('system');
system.args;
示例
查看以下示例以了解此属性的工作原理。
var system = require('system');
console.log(system.args.length);
if (system.args.length>0) {
console.log(JSON.stringify(system.args));
}
phantom.exit();
上述程序生成以下输出。
Command − phantomsjs args.js http://localhost/tasks/request.html
2 ["args.js","http://localhost/tasks/request.html"]
第一个值是文件的名称,下一个值是传递的 URL。您可以在命令行中传递更多参数,并使用 system.args 获取相同的参数。
env
env 属性返回系统的详细信息。
语法
其语法如下 −
var system = require('system');
system.env;
示例
var system = require('system');
console.log(JSON.stringify(system.env));
phantom.exit();
上述程序生成以下输出。
{"=::":"::\","=C:":"C:\phantomjs\bin","=ExitCode":"00000000","ALLUSERSPROFILE":
"C:\ProgramData","APPDATA":"C:\Users\UserName\AppData\Roaming","COMPUTERNAME":
"X","ComSpec":"C:\Windows\system32\cmd.exe","CommonProgramFiles":
"C:\Program Files (x86)\Common Files","CommonProgramFiles(x86)":
"C:\Program Files (x86)\Common Files","CommonProgramW6432":
"C:\Program Files\Common Files","FP_NO_HOST_CHECK":"NO","HOMEDRIVE":"C:",
"HOMEPATH":"\Users\UserName","LOCALAPPDATA":
"C:\Users\UserName\AppData\Local","LOGONSERVER":"\\MicrosoftAccount",
"NUMBER_OF_PROCESSORS":"2","OS":"Windows_NT","PATHEXT":".COM;.EXE;.BAT;.CMD;.VBS ;
.VBE;.JS;.JSE;.WSF;.WSH;.MSC","PROCESSOR_ARCHITECTURE":"x86","PROCESSOR_ARCHITEW64 32":
"AMD64","PROCESSOR_IDENTIFIER":"Intel64 Family 6 Model 58Stepping9,GenuineIntel",
"PROCESSOR_LEVEL":"6","PROCESSOR_REVISION":"3a09","PROMPT":
"$P$G","PSModulePath":"C:\Windows\system32\WindowsPowerShell\v1.0\
Modules\" ,"PUBLIC":"C:\Users\Public","Path":
"C:\Program Files\Dell\DW WLAN Card;
c:\Program Files (x86)\Intel\iCLS Client\;c:\Program Files\Intel\iCLSClient\;
C:\Windows\system32;C:\Windows;C:\Windows\System32\ \Wbem;
C:\Windows\System32\WindowsPowerShell\v1.0\;
C:\Program Files\Intel\Intel(R) Management Engine Components\DAL;
C:\Program Files\Intel\Intel(R) Management Engine Components\IPT;
C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\DAL;
C:\Program Files (x86)\Intel\Intel(R)
ManagementEngineComponents\IPT;c:\ProgramFiles\WIDCOMM\BluetoothSoftware\;
c:\ProgramFiles\WIDCOMM\BluetoothSoftware\syswow64;
C:\ProgramFiles(x86)\WindowsLive\Shared;C:\ProgramFiles\nodejs\;
C:\ProgramFiles\Git\cmd;C:\ProgramFiles\ OpenVPN\bin;
C:\ProgramFiles(x86)\Skype\Phone\;C:\Users\UserName\AppData\Roaming
\npm","ProgramData":
"C:\ProgramData","ProgramFiles":"C:\ProgramFiles(x86)",
"ProgramFiles(x86)":"C:\ProgramFiles(x86)","ProgramW6432":
"C:\ProgramFiles","SESSIONNAME":"Console","SystemDrive":
"C:","SystemRoot":"C:\Windows","TEMP":"C:\Users\ \Username~1\AppData\Local\Temp",
"TMP":"C:\Users\Username~1\AppData\Local\Temp",
"USERDOMAIN":"USER","USERDOMAIN_ROAMINGPROFILE":"USER","USERNAME":"X Y","USERPROFILE":
"C:\Users\X Y","windir":"C:\Windows"}
OS
它返回所用操作系统的详细信息。它返回一个包含体系结构、操作系统名称和版本的对象。
语法
其语法如下 −
var system = require('system');
system.os;
示例
var system = require('system');
console.log(JSON.stringify(system.os));
phantom.exit();
上述程序生成以下输出。
{"architecture":"32bit","name":"windows","version":"8.1"}
pid
此属性返回进程 ID。
语法
其语法如下 −
var system = require('system');
system.pid;
示例
让我们看一个 pid 属性的示例。
var system = require('system');
console.log(system.pid);
phantom.exit();
上述程序生成以下输出。
2160
platform
此属性返回我们正在处理的平台。
语法
其语法如下 −
var system = require('system');
system.platform;
示例
var system = require('system');
console.log(system.platform);
phantom.exit();
上述程序生成以下输出。
Phantomjs
PhantomJS - Web 服务器模块属性
PhantomJS 使用名为 mongoose 的嵌入式 Web 服务器。目前,PhantomJS 无法与任何其他生产 Web 服务器连接。就连接而言,它一次可以处理 10 个连接,并且超过 10 个请求将在队列中等待。
要启动 Web 服务器,我们需要使用以下语法 −
var webserver = require ('webserver');
让我们了解 Port 属性,该属性用于侦听发送到 Web 服务器的请求。
port
Web 服务器的 Port 属性用于侦听发送给它的请求。
语法
其语法如下 −
var server = require('webserver').create();
var listening = server.listen(port, function (request, response) {});
示例
让我们举一个例子来了解 port 属性的工作原理。
var webserver = require('webserver');
var server = webserver.create();
var service = server.listen(8080,function(request,response){
});
if(service) console.log("server started - http://localhost:" + server.port);
上述程序生成以下输出。
server started - http://localhost:8080
PhantomJS - Web 服务器模块方法
在本章中,我们将讨论 PhantomJS 的 Web 服务器模块的各种方法。
close
close 方法用于关闭 Web 服务器。
语法
其语法如下 −
var server = require('webserver').create();
server.close();
示例
以下示例展示了如何使用 close 方法。
var webserver = require('webserver');
var server = webserver.create();
var service = server.listen(8080,function(request,response){
});
if(service) console.log("server started - http://localhost:" + server.port);
console.log(server.port);
server.close();
console.log(server.port);
上述程序生成以下输出。
server started - http://localhost:8080 8080
在这里,我们在关闭服务器后对 server.port 进行了控制。因此,由于 Web 服务器已关闭,因此它不会响应。
listen
server.listen 方法采用端口和回调函数以及两个参数,即 - Request Object 和 Response Object。
Request Object 包含以下属性 −
Method − 这定义了方法 GET /POST。
URL − 这显示请求的 URL。
httpVersion − 这显示实际的 http 版本。
Headers −这将显示所有带有键值对的标头。
Post − 请求正文仅适用于 post 方法。
postRaw − 如果 Content-Type 标头设置为"application/x-www-formurlencoded",则帖子的原始内容将存储在此额外属性 (postRaw) 中,然后该帖子将自动使用 URL 解码版本的数据进行更新。
Response Object 包含以下属性 −
Headers − 包含所有 HTTP 标头作为键值对。应在首次调用 write 之前设置它。
SetHeader −这将设置一个特定的标头。
Header (name) − 它返回给定标头的值。
StatusCode − 它设置返回的 HTTP 状态代码。
SetEncoding (encoding) − 它用于转换给定给 write() 的数据。默认情况下,数据将转换为 UTF-8。如果数据是二进制字符串,则指示"二进制"。如果数据是缓冲区(例如来自 page.renderBuffer),则不需要。
Write (data) − 它发送响应主体的数据。可以多次调用。
WriteHead (statusCode, headers) − 它向请求发送响应标头。状态代码是 3 位 HTTP 状态代码(例如 404)。最后的参数和标头是响应标头。
Close − 它关闭 http 连接。
CloseGracefully − 它与 close() 类似,但它确保首先发送了响应标头。
语法
其语法如下 −
var server = require('webserver').create();
var listening = server.listen(8080, function (request, response) {}
示例
让我们举一个例子来了解 listen 方法的工作原理。
var page = require('webpage').create();
var server = require('webserver').create();
var port = 8080;
var listening = server.listen(8080, function (request, response) {
console.log("GOT HTTP REQUEST");
console.log(JSON.stringify(request, null, 4));
// 我们在这里设置标头
response.statusCode = 200;
response.headers = {"Cache": "no-cache", "Content-Type": "text/html"};
// 上面的标头现在将被隐式发送
// 现在我们编写正文
response.write("<html><head><title>Welcone to Phantomjs</title></head>");
response.write("<body><p>Hello World</p></body></html>");
response.close();
});
if (!listening) {
console.log("could not create web server listening on port " + port);
phantom.exit();
}
var url = "http://localhost:" + port + "/foo/response.php";
console.log("sending request to :" +url);
page.open(url, function (status) {
if (status !== 'success') {
console.log('page not opening');
} else {
console.log("Getting response from the server:");
console.log(page.content);
}
phantom.exit();
});
上述程序生成以下输出。
sending request to :http://localhost:8080/foo/response.php
GOT HTTP REQUEST {
"headers": {
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "en-IN,*",
"Connection": "Keep-Alive",
"Host": "localhost:8080",
"User-Agent": "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/538.1
(KHTML, like Gecko) PhantomJS/2.1.1 Safari/538.1"
},
"httpVersion": "1.1",
"method": "GET",
"url": "/foo/response.php"
}
Getting response from the server:
<html><head><title>Welcone to Phantomjs</title></head><body><p>Hello World</p></body>
</html>
PhantomJS - 命令行界面
可以使用关键字"phantomjs"和文件名称来执行 PhantomJS。例如,"phantomjs file.js"。
您还可以将参数传递给"file.js",如下所示 −
phantomjs [options] file.js arg1 arg2 ...
让我们来看看命令行中可用的一些选项。
| S.No | 选项 &描述 |
|---|---|
| 1 | --help 或 –h 将显示所有命令行选项。立即停止并且不会运行传递的脚本。 |
| 2 | --version 或 –v 打印正在运行的 PhantomJS 版本。这将停止要运行的脚本的执行。 |
| 3 | --debug[true|false] 打印警告和调试消息。默认情况下,它设置为 false。您也可以使用 [yes|no]。 |
| 4 | --cookies-file = /path/to/cookies.txt 用于存储持久性 cookie 的文件名。 |
| 5 | --diskcache=[true|false] 启用磁盘缓存。它还接受值 [yes|no] |
| 6 | --disk-cahe-path 磁盘缓存的路径。 |
| 7 | --ignore-sslerrors=[true|false] 忽略 SSL 错误。例如 - 过期或自签名证书错误。默认值为 false。它也接受值 [yes|no]。 |
| 8 | --loadimages=[true|false] 加载所有内联图像。默认值为 true。它还需要 [yes|no]。 |
| 9 | --local-storagepath=/some/path 保存 LocalStorage 内容和 WebSQL 内容的路径。 |
| 10 | --local-storagequota=number 允许数据的最大大小。 |
| 11 | --local-url-access 允许使用'file:///' URL(默认为 true)。 |
| 12 | --local-to-remote-urlaccess=[true|false] 允许本地内容访问远程 URL。默认值为 false。它还可以使用值 [yes|no]。 |
| 13 | --max-disk-cachesize=size 限制磁盘缓存的大小(以 KB 为单位) |
| 14 | --offline-storage-path 指定离线存储的位置。 |
| 15 | --offline-storage-quota 设置离线存储的最大大小(以 KB 为单位)。 |
| 16 | --outputencoding=encoding 设置用于终端输出的编码。默认为 utf-8。 |
| 17 | --proxy=address:port 指定要使用的代理服务器(例如 – proxy=192.168.1.1:8080) |
| 18 | --proxytype=[http|socks5|none] 指定代理服务器的类型(默认为 http) |
| 19 | --proxy-auth 代理的身份验证信息。例如 – --proxy-auth=username:password |
| 20 | --scriptencoding=encoding 设置脚本使用的编码。默认为 utf8。 |
| 21 | --script-language 设置脚本语言。 |
PhantomJS - 屏幕截图
PhantomJS 在截取网页屏幕截图和将网页转换为 PDF 方面非常有用。我们在这里给出了一个简单的示例来演示它的工作原理。
示例
var page = require('webpage').create();
page.open('http://phantom.org/',function(status){
page.render('phantom.png');
phantom.exit();
});
执行上述程序,输出将保存为 phantom.png。
将网页转换为 PDF
PhantomJS 还有助于将网页转换为添加了页眉和页脚的 PDF。请查看以下示例以了解其工作原理。
var wpage = require('webpage').create();
var url = "https://en.wikipedia.org/wiki/Main_Page";
var output = "test.pdf";
wpage.paperSize = {
width: screen.width+'px',
height: '1500px',
margin: {
'top':'50px',
'left':'50px',
'rigtht':'50px'
},
orientation:'portrait',
header: {
height: "1cm",
contents: phantom.callback(function(pageNumber, nPages) {
return "<h5>Header <b>" + pageNumber + " / " + nPages + "</b></h5>";
})
},
footer: {
height: "1cm",
contents: phantom.callback(function(pageNumber, nPages) {
return "<h5>Footer <b>" + pageNumber + " / " + nPages + "</b></h5>";
})
}
}
wpage.open(url, function (status) {
if (status !== 'success') {
console.log('Page is not opening');
phantom.exit();
} else {
wpage.render(output);
phantom.exit();
}
});
上述程序生成以下输出。
The above will convert the page into pdf and will be saved in test.pdf
将 Canvas 转换为图像
Phantomjs 可以轻松将 Canvas 转换为图像。查看以下示例以了解其工作原理。
var page = require('webpage').create();
page.content = '<html><body><canvas id="surface" width="400" height="400"></canvas></body></html>';
page.evaluate(function() {
var context,e1;
el = document.getElementById('surface');
context = el.getContext('2d');
context.font = "30px Comic Sans MS";
context.fillStyle = "red";
context.textAlign = "center";
context.fillText("Welcome to PhantomJS ", 200, 200);
document.body.style.backgroundColor = 'white';
document.body.style.margin = '0px';
});
page.render('canvas.png');
phantom.exit();
上述程序生成以下输出。
h1>PhantomJS - 页面自动化
PhantomJS 在其网页模块 API 的帮助下,可以操作网页并执行诸如 DOM 操作、单击按钮等操作。
从页面获取图像
以下程序展示了如何使用 PhantomJS 从页面获取图像。
var wpage = require('webpage').create();
wpage.onConsoleMessage = function(str) {
console.log(str.length);
}
wpage.open("http://phantomjs.org", function(status) {
console.log(status);
var element = wpage.evaluate(function() {
var imgdata = document.querySelectorAll('img');
var imgsrc = [];
if (imgdata) {
for (var i in imgdata) {
imgsrc.push(imgdata[0].src);
}
}
return imgsrc;
});
console.log(JSON.stringify(element));
});
上述程序生成以下输出。
Success ["http://phantomjs.org/img/phantomjslogo.png","http://phantomjs.org/img/phantom js-logo.png","http://phantomjs.org/img/phantomjslogo.png","http://phantomjs.org /img/phantomjs-logo.png"]
可以使用 injectJS 网页方法 在页面中包含外部 JavaScript。有许多属性和方法,可以帮助页面自动化并执行许多其他操作。您可以参考网页模块,其中详细解释了属性和方法。
PhantomJS - 网络监控
借助 PhantomJS,我们可以监控网络并验证特定网页的行为和性能。PhantomJS 中有回调,即 onResourceRequested 和 onResourceReceived,它们有助于监控给定页面的流量。
示例
以下示例展示了如何使用 PhantomJS 监控给定页面的流量。
function createHAR(address, title, startTime, resources) {
// 此函数格式化来自 onresourcerequest 和 onresourcereceived 的数据
var entries = [];
resources.forEach(function (resource) {
var request = resource.request, startReply = resource.startReply,
endReply = resource.endReply;
if (!request || !startReply || !endReply) {
return;
}
// 从 HAR 文件中排除数据 URI,因为
// 它们未包含在规范中
if (request.url.match(/(^data:image\/.*)/i)) {
return;
}
entries.push ({
startedDateTime: request.time.toISOString(),
time: endReply.time - request.time,
request: {
method: request.method,
url: request.url,
httpVersion: "HTTP/1.1",
cookies: [], headers: request.headers,
queryString: [],
headersSize: -1,
bodySize: -1
},
response: {
status: endReply.status,
statusText: endReply.statusText,
httpVersion: "HTTP/1.1",
cookies: [],
headers: endReply.headers,
redirectURL: "",
headersSize: -1,
bodySize: startReply.bodySize,
content: {
size: startReply.bodySize,
mimeType: endReply.contentType
}
},
cache: {},
timings: {
blocked: 0,
dns: -1,
connect: -1,
send: 0,
wait: startReply.time - request.time,
receive: endReply.time - startReply.time,
ssl: -1
},
pageref: address
});
});
return {
log: {
version: '1.2', creator: {
name: "PhantomJS",
version: phantom.version.major + '.' + phantom.version.minor +
'.' + phantom.version.patch
},
pages: [{
startedDateTime: startTime.toISOString(),
id: address,
title: title,
pageTimings: {
onLoad: page.endTime - page.startTime
}
}],
entries: entries
}
};
}
var page = require('webpage').create(), system = require('system');
var fs = require('fs');
if (system.args.length === 1) {
console.log('Usage: netsniff.js <some URL>');
phantom.exit(1);
} else {
page.address = system.args[1];
page.resources = [];
page.onLoadStarted = function () { // 页面加载时调用
page.startTime = new Date();
};
page.onResourceRequested = function (req) {
// 当从给定的页面 URL 请求任何文件时调用
page.resources[req.id] = {
request: req,
startReply: null,
endReply: null
};
};
page.onResourceReceived = function (res) {
//当收到任何文件时调用。
if (res.stage === 'start') {
page.resources[res.id].startReply = res;
}
if (res.stage === 'end') {
page.resources[res.id].endReply = res;
}
};
page.open(page.address, function (status) { // 打开给定的页面网址
var har;
if (status !== 'success') {
console.log('FAIL to load the address');
phantom.exit(1);
} else {
page.endTime = new Date();
page.title = page.evaluate(function () { // 获取页面标题
return document.title;
});
har = createHAR(page.address, page.title, page.startTime, page.resources);
// 使用页面 URL、开始时间和页面资源调用 createHAR 函数。
// console.log(JSON.stringify(har, undefined, 4));
fs.write('log.txt', JSON.stringify(har, undefined, 4), 'w');
// 日志收集在 log.txt 文件中。
phantom.exit();
}
});
}
提供给 HAR 预览的 log.txt 示例
{
"log": {
"version": "1.2",
"creator": {
"name": "PhantomJS",
"version": "2.1.1"
},
"pages": [
{
"startedDateTime": "2017-05-21T13:41:21.824Z",
"id": "http://www.sample.com",
"title": "Free Sample Products – Sample.com ≫ Free Samples,
Free Product Samples, Product Test Marketing",
"pageTimings": {
"onLoad": 11081
}
}
],
"entries": [
{
"startedDateTime": "2017-05-21T13:41:21.815Z",
"time": 1999,
"request": {
"method": "GET",
"url": "http://www.sample.com/",
"httpVersion": "HTTP/1.1",
"cookies": [],
"headers": [
{
"name": "Accept",
"value": "text/html,application/xhtml+xml,
application/xml;q = 0.9,*/*;q = 0.8"
},
{
"name": "User-Agent",
"value": "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/538.1
(KHTML, like Gecko) PhantomJS/2.1.1 Safari/538.1"
}
],
"queryString": [],
"headersSize": -1,
"bodySize": -1
},
"response": {
"status": 301,
"statusText": "Moved Permanently",
"httpVersion": "HTTP/1.1",
"cookies": [],
"headers": [
{
"name": "Date",
"value": "Sun, 21 May 2017 13:41:25 GMT"
},
{
"name": "Server",
"value": "Apache/2.2.14 (Ubuntu)"
},
{
"name": "Location",
"value": "http://sample.com//"
},
{
"name": "Vary",
"value": "Accept-Encoding"
},
{
"name": "Content-Encoding",
"value": "gzip"
},
{
"name": "Keep-Alive",
"value": "timeout = 15, max = 100"
},
{
"name": "Connection",
"value": "Keep-Alive"
},
{
"name": "Content-Type",
"value": "text/html; charset = iso-8859-1"
}
],
"redirectURL": "",
"headersSize": -1,
"bodySize": 307,
"content": {
"size": 307,
"mimeType": "text/html; charset = iso-8859-1"
}
},
"cache": {},
"timings": {
"blocked": 0,
"dns": -1,
"connect": -1,
"send": 0,
"wait": 1999,
"receive": 0,
"ssl": -1
},
"pageref": "http://www.sample.com"
},
]
{
"startedDateTime": "2017-05-21T13:41:24.898Z",
"time": 885,
"request": {
"method": "GET",
"url": "http://sample.com/",
"httpVersion": "HTTP/1.1",
"cookies": [],
"headers": [
{
"name": "Accept",
"value": "text/html,application/xhtml+xml,
application/xml;q = 0.9,*/*;q = 0.8"
},
{
"name": "User-Agent",
"value": "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/538.1
(KHTML, like Gecko) PhantomJS/2.1.1 Safari/538.1"
}
],
"queryString": [],
"headersSize": -1,
"bodySize": -1
},
"response": {
"status": 200,
"statusText": "OK",
"httpVersion": "HTTP/1.1",
"cookies": [],
"headers": [
{
"name": "Date",
"value": "Sun, 21 May 2017 13:41:27 GMT"
},
{
"name": "Server",
"value": "Apache/2.2.14 (Ubuntu)"
},
{
"name": "X-Powered-By",
"value": "PHP/5.3.2-1ubuntu4.29"
},
{
"name": "X-Pingback",
"value": "http://sample.com/xmlrpc.php"
},
{
"name": "Link",
"value": "<http://sample.com/wp-json/>;
rel = \"https://api.w.org/\", <http://wp.me/P6Jj5H-4>;
rel = shortlink"
},
{
"name": "Vary",
"value": "Accept-Encoding"
},
{
"name": "Content-Encoding",
"value": "gzip"
},
{
"name": "Keep-Alive",
"value": "timeout = 15, max = 99"
},
{
"name": "Connection",
"value": "Keep-Alive"
},
{
"name": "Content-Type",
"value": "text/html; charset = UTF-8"
}
],
"redirectURL": "",
"headersSize": -1,
"bodySize": 1969,
"content": {
"size": 1969,
"mimeType": "text/html; charset = UTF-8"
}
},
"cache": {},
"timings": {
"blocked": 0,
"dns": -1,
"connect": -1,
"send": 0,
"wait": 869,
"receive": 16,
"ssl": -1
},
"pageref": http://www.sample.com
},
{
"startedDateTime": "2017-05-21T13:41:25.767Z",
"time": 388,
"request": {
"method": "GET",
"url": "http://sample.com/wpcontent/themes/samplecom/style.css",
"httpVersion": "HTTP/1.1",
"cookies": [],
"headers": [
{
"name": "Accept",
"value": "text/css,*/*;q = 0.1"
},
{
"name": "Referer",
"value": "http://sample.com/"
},
{
"name": "User-Agent",
"value": "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/538.1
(KHTML, like Gecko) PhantomJS/2.1.1 Safari/538.1"
}
],
"queryString": [],
"headersSize": -1,
"bodySize": -1
},
"response": {
"status": 200,
"statusText": "OK",
"httpVersion": "HTTP/1.1",
"cookies": [],
"headers": [
{
"name": "Date",
"value": "Sun, 21 May 2017 13:41:27 GMT"
},
{
"name": "Server",
"value": "Apache/2.2.14 (Ubuntu)"
},
{
"name": "Last-Modified",
"value": "Fri, 22 Apr 2011 00:32:22 GMT"
},
{
"name": "ETag",
"value": "\"e1d7-1836-4a176fdbbd180\""
},
{
"name": "Accept-Ranges",
"value": "bytes"
},
{
"name": "Vary",
"value": "Accept-Encoding"
},
{
"name": "Content-Encoding",
"value": "gzip"
},
{
"name": "Keep-Alive",
"value": "timeout = 15, max = 98"
},
{
"name": "Connection",
"value": "Keep-Alive"
},
{
"name": "Content-Type",
"value": "text/css"
}
],
"redirectURL": "",
"headersSize": -1,
"bodySize": 3174,
"content": {
"size": 3174,
"mimeType": "text/css"
}
},
"cache": {},
"timings": {
"blocked": 0,
"dns": -1,
"connect": -1,
"send": 0,
"wait": 388,
"receive": 0,
"ssl": -1
},
"pageref": "http://www.sample.com"
}
}
}
Output
上述程序生成以下输出。
所有日志都收集在 .txt 文件 中,之后使用 HAR 预览将其转换为上述格式,例如 (http://www.softwareishard.com/har/viewer/)
PhantomJS - 测试
PhantomJS 为网页提供了大量 API,可提供所有详细信息。PhantomJS 可用于测试,如获取页面内容、进行屏幕共享、将页面转换为 pdf 等。市场上有许多流行的测试库,可与 PhantomJS 一起使用并用于测试。
一些可与 PhantomJS 配合使用的流行框架如下 −
- Mocha
- Jasmine
- Qunit
- Hiro
- Laika
- Buster.JS
- WebDriver
示例 - PhantomJS 与 Qunit
(function () {
var url, timeout,args = require('system').args, page = require('webpage').create();
url = args[1];
timeout = parseInt(10, 10);
page.onConsoleMessage = function (msg) {
//打印所有控制台消息
console.log(msg);
};
page.onInitialized = function () { // 在页面初始化时调用
page.evaluate(callqunit);
};
page.onCallback = function (message) { // called from
var result, failed;
if (message) {
if (message.name === 'QUnit.done') {
result = message.data;
failed = !result || !result.total || result.failed;
if (!result.total) {
console.error('No tests were executed');
}
pageexit(failed ? 1 : 0);
}
}
};
page.open(url, function (status) { // opening page
if (status !== 'success') {
console.error('Unable to access network: ' + status);
pageexit(1);
} else {
var checkqunit = page.evaluate(function () {
//评估页面并检查是否为 qunit 对象
is present on the given page url
return (typeof QUnit === 'undefined' || !QUnit);
});
if (checkqunit) {
console.error('Qunit scripts are not present on the page');
pageexit(1);
}
//使用 10 秒的超时时间,否则将打印来自控制台的消息。
setTimeout(function () {
console.error('The specified timeout of ' + timeout + ' seconds has expired.
Aborting...');
pageexit(1);
}, timeout * 1000);
}
});
function callqunit() {
qunit.html
<!DOCTYPE html>
<html>
<head>
<meta charset = "utf-8">
<meta name = "viewport" content = "width = device-width">
<title>QUnit Example</title>
<link rel = "stylesheet" href = "https://code.jquery.com/qunit/qunit-2.3.2.css">
</head>
<body>
<div id = "qunit"></div>
<div id = "qunit-fixture"></div>
<script src = "https://code.jquery.com/qunit/qunit-2.3.2.js"></script>
</body>
</html>
输出
命令 − phantomjs qunit.js http://localhost/tasks/qunit.html
上述程序生成以下输出。
{"passed":3,"failed":2,"total":5,"runtime":23}
Time taken is 23ms to run 5 tests.
3 passed, 2 failed.
PhantomJS - REPL
REPL 代表 Read Eval Print Loop。在 PhantomJS 中,REPL 是一种测试 JavaScript 代码的交互模式。您可以执行与在 Google Chrome Inspector 或 Firebug 中相同的操作,以直接在控制台上执行某些代码。REPL 返回相同的平台来执行脚本。
输入的命令将发送到解释器进行立即解释(EVAL)并提供反馈(PRINT)。在命令行中输入 PhantomJS,它将带您进入交互模式,您可以在其中直接执行代码。
语法
其语法如下 −
Phantomjs
示例
以下示例演示了 REPL 在 PhantomJS 中的工作方式。
phantomjs> console.log("Welcome to phantomjs");
Welcome to phantomjs
Undefined
phantomjs> window.navigator {
"appCodeName": "Mozilla",
"appName": "Netscape",
"appVersion": "5.0 (Windows NT 6.2; WOW64) AppleWebKit/538.1 (KHTML, like Gecko)
PhantomJS/2.1.1 Safari/538.1",
"cookieEnabled": true,
"language": "en-IN",
"mimeTypes": {
"length": 0
},
"onLine": false,
"platform": "Win32",
"plugins": {
"length": 0
},
"product": "Gecko
"productSub": "20030107",
"userAgent": "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/538.1 (KHTML, like Gecko)
PhantomJS/2.1.1 Safari/538.1",
"vendor": "Apple Computer, Inc.",
"vendorSub": ""
}
phantomjs>
To find the version
phantomjs> phantom.version {
"major": 2,
"minor": 1,
"patch": 1
}
phantomjs>
执行每个命令并显示结果。使用 CTRL+C、CTRL+D 或 phantom.exit() 退出交互模式。
使用 向上/向下 箭头键收听先前输入的命令。
还有另一个称为 自动完成 的功能,它有助于记住命令。只需输入"phantom"并点击"Tab"按钮即可获得可执行的可用命令列表。
输出
上述程序生成以下输出。
phantomjs> phantom.→| phantomjs> phantom.cookies→| phantomjs> phantom.exit→| phantomjs> phantom.version→|
PhantomJS - 示例
在本章中,我们将提供一些更实际的示例来帮助您了解 PhantomJS 的一些重要功能。
示例 1 - 查找页面速度
在此示例中,我们将使用 PhantomJS 查找任何给定页面 URL 的页面速度。
var page = require('webpage').create(),
system = require('system'),
t, address;
if (system.args.length === 1) {
console.log('Usage: loadspeed.js <some URL>');
phantom.exit(1);
} else {
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('Page title is ' + page.evaluate(function () {
return document.title;
}));
console.log('Loading time ' + t + ' msec');
}
phantom.exit();
});
}
上述程序生成以下输出。
命令 − phantomjs pagespeed.js http://www.google.com
Page title is Google Loading time 1396 msec
示例 2 - 向页面发送点击事件
在下面的示例中,我们将使用 PhantomJS 向页面发送 点击事件。
var page = require('webpage').create();
page.onConsoleMessage = function(str) {
console.log(str);
}
page.open('http://phantomjs.org/api/phantom/', function(status) {
page.render('beforeclick.png');
console.log(page.url);
var element = page.evaluate(function() {
return document.querySelector('img[src = "http://phantomjs.org/img/phantomjslogo.png"]');
});
page.sendEvent('click', element.offsetLeft, element.offsetTop, 'left');
window.setTimeout(function () {
console.log(page.url);
page.render('afterclick.png');
phantom.exit();
}, 5000);
console.log('element is ' + element);
});
上述程序生成以下输出。
http://phantomjs.org/api/phantom/ element is [object Object] http://phantomjs.org/
我们的程序将在 bin 文件夹中创建以下两个 png 图像。这两幅图像显示了上述程序执行前后的差异。
示例 3 - 提交表单
以下示例显示如何使用 PhantomJS 提交表单。
var wpage = require('webpage').create();
wpage.open("http://localhost/tasks/submitform.html", function(status) {
console.log(status);
wpage.uploadFile('input[name = fileToUpload]', 'output.png');
wpage.render("sform.png");
var element = wpage.evaluate(function() {
return document.querySelector('input[type = "submit"]');
// 使用 queryselector 获取提交按钮的详细信息。
});
wpage.sendEvent('click', element.offsetLeft, element.offsetTop, 'left');
// sendevent 用于发送点击事件,并给出左侧和顶部
position of the submit button.
window.setTimeout(function () {
console.log(wpage.url);
wpage.render("submit.png"); // 截图保存在submit.png中
phantom.exit();
}, 5000);
console.log('element is ' + element);
});
submitform.html
以下代码显示如何使用 submitform.html 文件。
<html>
<head>
<title>Window 2</title>
</head>
<body>
<form action = "submitform.php" method = "post" enctype = "multipart/form-data"
id = "form1">
<input type = "file" name = "fileToUpload" id = "fileToUpload">
<input type = "submit" value = "Upload Image" name = "submit">
</form>
</body>
</html>
表单提交后,将转到 submitform.php。
submitform.php
submitform.php 仅打印文件的详细信息。
<?php print_r($_FILES); ?>
上述程序生成以下输出。
Success element is [object Object] http://localhost/tasks/submitform.php
图片
以下是文件上传和表单提交的图片。

