/
path---2014-phantomjs-c67660daf052a6dfd4f0.js.map
1 lines (1 loc) · 132 KB
/
path---2014-phantomjs-c67660daf052a6dfd4f0.js.map
1
{"version":3,"sources":["webpack:///path---2014-phantomjs-c67660daf052a6dfd4f0.js","webpack:///./.cache/json/2014-phantomjs.json"],"names":["webpackJsonp","562","module","exports","data","site","siteMetadata","title","subtitle","copyright","author","name","rss","email","github","markdownRemark","id","html","excerpt","fields","tagSlugs","frontmatter","tags","date","description","pathContext","slug"],"mappings":"AAAAA,cAAc,iBAERC,IACA,SAAUC,EAAQC,GCHxBD,EAAAC,SAAkBC,MAAQC,MAAQC,cAAgBC,MAAA,YAAAC,SAAA,YAAAC,UAAA,yBAAAC,QAA0FC,KAAA,KAAAC,IAAA,IAAAC,MAAA,oBAAAC,OAAA,gBAA0EC,gBAAmBC,GAAA,wGAAAC,KAAA;AAAm2jDC,QAAA,qHAAAC,QAA0wDC,UAAA,kFAA6FC,aAAgBd,MAAA,gBAAAe,MAAA,8CAAAC,KAAA,2BAAAC,YAAA,QAAqIC,aAAgBC,KAAA","file":"path---2014-phantomjs-c67660daf052a6dfd4f0.js","sourcesContent":["webpackJsonp([81292661065823],{\n\n/***/ 562:\n/***/ (function(module, exports) {\n\n\tmodule.exports = {\"data\":{\"site\":{\"siteMetadata\":{\"title\":\"Step Over\",\"subtitle\":\"有趣的灵魂终会相遇\",\"copyright\":\"© All rights reserved.\",\"author\":{\"name\":\"周骅\",\"rss\":\"#\",\"email\":\"zhou--hua@163.com\",\"github\":\"zhouhua-js\"}}},\"markdownRemark\":{\"id\":\"/work/playground/zhouhua.site/src/pages/articles/2014/phantomjs.md absPath of file >>> MarkdownRemark\",\"html\":\"<p>phantomjs实现了一个无界面的webkit浏览器。虽然没有界面,但dom渲染、js运行、网络访问、canvas/svg绘制等功能都很完备,在页面抓取、页面输出、自动化测试等方面有广泛的应用。</p>\\n<h2>安装</h2>\\n<p>下载phantomjs(<a href=\\\"https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-1.9.7-windows.zip\\\">官方下载</a>,下载失败请访问<a href=\\\"http://zhouhua.qiniudn.com/work/Node.js/phantomjs.zip\\\">另一个下载点</a>)。解压到任意目录,并将包含phantomjs.exe的目录添加到系统路径。</p>\\n<p>如果要借助phantomjs进行无头测试,请参考各个测试框架的说明,或者参考phantomjs的官方文档:<a href=\\\"http://phantomjs.org/headless-testing.html\\\">http://phantomjs.org/headless-testing.html</a>。</p>\\n<h2>使用说明</h2>\\n<h3>简单示例</h3>\\n<div class=\\\"gatsby-highlight\\\">\\n <pre class=\\\"language-js test.js\\\"><code>var page = require('webpage').create(),\\n system = require('system'),\\n address;\\nif (system.args.length === 1) {\\n phantom.exit(1);\\n} else {\\n address = system.args[1];\\n page.open(address, function (status) {\\n console.log(page.content);\\n phantom.exit();\\n });\\n}</code></pre>\\n </div>\\n<p>运行:</p>\\n<div class=\\\"gatsby-highlight\\\">\\n <pre class=\\\"language-bash\\\"><code>phantomjs ./test.js http://baidu.com\\n</code></pre>\\n </div>\\n<p>这个例子简单地展示了通过phantom访问baidu.com,并输入html内容。使用方式就像使用Node.js运行js代码一样。在phantom运行时,它会向当前代码运行环境注入phantom对象。如上面代码中,通过phantom对象控制程序终结。示例中其他代码的含义以及更多深入的用法,将在下文中展开。</p>\\n<hr>\\n<h3>window对象</h3>\\n<p>在使用phantom时,我首先关注的是DOM和BOM接口。不过这不是一个问题,看了下面的代码就能了解:</p>\\n<div class=\\\"gatsby-highlight\\\">\\n <pre class=\\\"language-js test.js\\\"><code>console.log(window === this);\\nphantom.exit();</code></pre>\\n </div>\\n<p>运行:</p>\\n<div class=\\\"gatsby-highlight\\\">\\n <pre class=\\\"language-bash\\\"><code>phantomjs ./test.js\\n</code></pre>\\n </div>\\n<p>结果为<code>true</code>。也就是说,就像浏览器环境一样,我们的代码运行在window环境下,可以很方便地进行DOM方面的操作。</p>\\n<blockquote>\\n<p>注:如果使用web page模块打开页面,则请不要在此window对象下进行任何DOM相关的操作,因为这个window并不是page对象内的window。如果想要执行dom相关操作,请参阅<code>page.evaluate()</code>部分。</p>\\n</blockquote>\\n<hr>\\n<h3>phantom对象</h3>\\n<p>之前的例子中我们已经初步认识了phantom对象。它的功能是定义和控制phantom运行环境的参数和流程。关键的API有:</p>\\n<ol>\\n<li>\\n<p><code>phantom.args</code> String[]\\n获取传给本JS程序的参数,需要与<code>system.args</code>进行区分(system模块详见下文),后者表示传给phantomjs引擎的参数。例如<code>phantomjs ./test.js http://baidu.com</code>这句语句,通过<code>phantom.args</code>,我们能得到的参数列表为<code>['http://baidu.com']</code>,而通过<code>system.args</code>则得到<code>['./test.js', 'http://baidu.com']</code>这样的参数列表。差异就在于是否包含当前脚本名称。不过<code>phantom.scriptName</code>这个API提供了获取脚本名称的功能。</p>\\n</li>\\n<li>\\n<p><code>phantom.cookies</code> Object[]\\n获取或设置cookies,不过对于设置建议使用其他的API完成。同时相关的API还有:</p>\\n<ul>\\n<li><code>phantom.addCookie(Object)</code> Boolean:添加cookie值</li>\\n<li><code>phantom.deleteCookie(cookieName)</code> Boolean:删除指定Cookie值</li>\\n<li><code>phantom.clearCookies()</code>:清空所有的cookie</li>\\n<li><code>phantom.cookiesEnabled</code> Boolean:获取或设置是否支持cookie</li>\\n</ul>\\n</li>\\n<li>\\n<p><code>phantom.injectJs(fileName)</code> Boolean:\\n把指定的外部JS文件注入到当前环境。执行这个方法时,phantomjs首先会从当前目录检索此文件,如果找不到,则再到<code>phantom.libraryPath</code>指定的路径寻找。<code>phantom.libraryPath</code>这个API基本上就是为<code>phantom.injectJs()</code>服务的。</p>\\n</li>\\n<li>\\n<p><code>phantom.onError</code>\\n当页面存在js错误,且没有被<code>page.onError</code>处理,则会被此handler捕获。下面是使用此API的一个例子。由于phantom环境下代码调试很困难,了解这些错误捕获的API也许会对我们的实际使用有所帮助。</p>\\n<div class=\\\"gatsby-highlight\\\">\\n <pre class=\\\"language-js\\\"><code>phantom<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function-variable function\\\">onError</span> <span class=\\\"token operator\\\">=</span> <span class=\\\"token keyword\\\">function</span><span class=\\\"token punctuation\\\">(</span>msg<span class=\\\"token punctuation\\\">,</span> trace<span class=\\\"token punctuation\\\">)</span> <span class=\\\"token punctuation\\\">{</span>\\n <span class=\\\"token keyword\\\">var</span> msgStack <span class=\\\"token operator\\\">=</span> <span class=\\\"token punctuation\\\">[</span><span class=\\\"token string\\\">'PHANTOM ERROR: '</span> <span class=\\\"token operator\\\">+</span> msg<span class=\\\"token punctuation\\\">]</span><span class=\\\"token punctuation\\\">;</span>\\n <span class=\\\"token keyword\\\">if</span> <span class=\\\"token punctuation\\\">(</span>trace <span class=\\\"token operator\\\">&</span>amp<span class=\\\"token punctuation\\\">;</span>amp<span class=\\\"token punctuation\\\">;</span><span class=\\\"token operator\\\">&</span>amp<span class=\\\"token punctuation\\\">;</span>amp<span class=\\\"token punctuation\\\">;</span> trace<span class=\\\"token punctuation\\\">.</span>length<span class=\\\"token punctuation\\\">)</span> <span class=\\\"token punctuation\\\">{</span>\\n msgStack<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">push</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">'TRACE:'</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n trace<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">forEach</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token keyword\\\">function</span><span class=\\\"token punctuation\\\">(</span>t<span class=\\\"token punctuation\\\">)</span> <span class=\\\"token punctuation\\\">{</span>\\n msgStack<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">push</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">' -&gt; '</span> <span class=\\\"token operator\\\">+</span> <span class=\\\"token punctuation\\\">(</span>t<span class=\\\"token punctuation\\\">.</span>file <span class=\\\"token operator\\\">||</span> t<span class=\\\"token punctuation\\\">.</span>sourceURL<span class=\\\"token punctuation\\\">)</span> <span class=\\\"token operator\\\">+</span> <span class=\\\"token string\\\">': '</span> <span class=\\\"token operator\\\">+</span> t<span class=\\\"token punctuation\\\">.</span>line <span class=\\\"token operator\\\">+</span> <span class=\\\"token punctuation\\\">(</span>t<span class=\\\"token punctuation\\\">.</span><span class=\\\"token keyword\\\">function</span> <span class=\\\"token operator\\\">?</span> <span class=\\\"token string\\\">' (in function '</span> <span class=\\\"token operator\\\">+</span> t<span class=\\\"token punctuation\\\">.</span><span class=\\\"token keyword\\\">function</span> <span class=\\\"token operator\\\">+</span><span class=\\\"token string\\\">')'</span> <span class=\\\"token punctuation\\\">:</span> <span class=\\\"token string\\\">''</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n <span class=\\\"token punctuation\\\">}</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n <span class=\\\"token punctuation\\\">}</span>\\n console<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">error</span><span class=\\\"token punctuation\\\">(</span>msgStack<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">join</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">'\\\\n'</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n phantom<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">exit</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token number\\\">1</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n<span class=\\\"token punctuation\\\">}</span><span class=\\\"token punctuation\\\">;</span>\\n</code></pre>\\n </div>\\n</li>\\n<li>\\n<p><code>phantom.exit(returnValue)</code>\\n这个API已经见过多次了,它的作用是退出程序,可以设置一个退出代码,默认是0。</p>\\n</li>\\n</ol>\\n<hr>\\n<h3>web page 模块</h3>\\n<p>web page模块的功能是处理具体的页面。使用时需要引入模块,并创建实例:</p>\\n<div class=\\\"gatsby-highlight\\\">\\n <pre class=\\\"language-js\\\"><code><span class=\\\"token keyword\\\">var</span> webPage <span class=\\\"token operator\\\">=</span> <span class=\\\"token function\\\">require</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">'webpage'</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n<span class=\\\"token keyword\\\">var</span> page <span class=\\\"token operator\\\">=</span> webPage<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">create</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n</code></pre>\\n </div>\\n<blockquote>\\n<p>本文中不经说明,<code>page</code>指代<code>require(&quot;webpage&quot;).create()</code>的实例。</p>\\n</blockquote>\\n<ol>\\n<li>\\n<p><code>page.cookies</code> Object[]\\n与上文中的<code>phantom.cookies</code>类似,表示本url下的cookie的读取。同样类似的API还有<code>addCookie()</code>、<code>deleteCookie()</code>、<code>clearCookies()</code>。</p>\\n</li>\\n<li>\\n<p>页面内容相关的API</p>\\n<ul>\\n<li><code>page.content</code> String:获取或设置当前页面的html。</li>\\n<li><code>page.plainText</code> String:这是一个只读属性,获取页面去除html标记的文本(考虑<code>$.text()</code>)。</li>\\n<li><code>page.url</code> String:只读,获取当前页面的url。</li>\\n<li><code>page.setContent()</code>:允许修改<code>page.content</code>和<code>page.url</code>内容,会触发reload。</li>\\n</ul>\\n</li>\\n<li>\\n<p><code>page.settings</code> Object\\n对于当前页面的一些配置项。此API必须在<code>page.open()</code>调用之前设置,否则不会起作用。以下是配置项:</p>\\n<ul>\\n<li><code>javascriptEnabled</code> 默认<code>true</code>:是否执行页面内的javascript</li>\\n<li><code>loadImages</code> 默认<code>true</code>:是否载入图片</li>\\n<li><code>userAgent</code> :传递给服务器的userAgent字符串</li>\\n<li><code>userName</code> :用于http访问授权的用户名</li>\\n<li><code>password</code> :用于http访问授权的密码</li>\\n<li><code>XSSAuditingEnabled</code> 默认<code>false</code>:是否监控跨域请求</li>\\n<li><code>resourceTimeout</code> 单位<code>ms</code>:定义资源请求的超时时间。如果设置了此项,则页面中如果有任何资源超过此时限未请求成功,则页面其他部分也会停止请求,并触发<code>onResourceTimeout()</code>事件处理。</li>\\n</ul>\\n</li>\\n<li>\\n<p><code>page.customHeaders</code> Object\\nphantom允许在请求时在http请求头部添加额外信息,此设置项对这个page里面所有的请求都生效(包含页面和其他资源的请求)。添加的信息并没有限制,但如果设置<code>User-Agent</code>的值,那么这个值会覆盖掉<code>page.settings</code>里的设置值。示例:</p>\\n<div class=\\\"gatsby-highlight\\\">\\n <pre class=\\\"language-js\\\"><code>page<span class=\\\"token punctuation\\\">.</span>customHeaders <span class=\\\"token operator\\\">=</span> <span class=\\\"token punctuation\\\">{</span>\\n <span class=\\\"token string\\\">\\\"X-Test\\\"</span><span class=\\\"token punctuation\\\">:</span> <span class=\\\"token string\\\">\\\"foo\\\"</span><span class=\\\"token punctuation\\\">,</span>\\n <span class=\\\"token string\\\">\\\"DNT\\\"</span><span class=\\\"token punctuation\\\">:</span> <span class=\\\"token string\\\">\\\"1\\\"</span>\\n<span class=\\\"token punctuation\\\">}</span><span class=\\\"token punctuation\\\">;</span>\\n</code></pre>\\n </div>\\n</li>\\n<li>\\n<p><code>page.libraryPath</code> String\\n与<code>phantom.libraryPath</code>类似,page对象也支持设置js文件路径,同时可以通过相应的<code>page.injectJs()</code>方法注入javascript文件。除了<code>page.injectJs()</code>方法外,还有<code>page.includeJs()</code>也可以加入javascript文件。它们的区别在于,<code>page.injectJs()</code>不强求此文件能访问得到,即使是一个不可访问的资源也可以。</p>\\n</li>\\n<li>\\n<p><code>page.navigationLocked</code> Boolean 默认<code>fasle</code>\\n设置是否允许离开当前页面,默认是允许。</p>\\n</li>\\n<li>\\n<p><code>page.open()</code>\\n此方法用于打开一个网页,是一个很重要的API,它有三种调用形式:</p>\\n<ul>\\n<li><code>open(url, callback)</code></li>\\n<li><code>open(url, method, callback)</code></li>\\n<li><code>open(url, method, data, callback)</code>\\n联想一下<code>$.ajax()</code>,可以更好理解这个API。对于这些参数,需要单独阐述的是<code>callback</code>。<code>callback()</code>会在页面载入完成后调用,由<code>page.onLoadFinished</code>调用(时机晚于<code>page.onLoadFinished</code>)。这个<code>callback</code>会接受一个参数<code>status</code>,可能值为<code>'success</code>和<code>'fail'</code>,指示页面是否加载成功。示例可以参考“简单示例”一节的例子。</li>\\n</ul>\\n</li>\\n<li>\\n<p><code>page.close()</code>\\n与<code>page.open()</code>对应,调用<code>page.close()</code>之后,会释放page所占用的内存,我们不可以在此之后再调用page实例。在实际的操作中,调用此方法并不会完成清空所占内存;javascript的垃圾回收机制也不会回收page实例。但在实际使用中,常常会遇到将一个page实例反复open的情况。在一个页面用完后,记得一定要执行<code>page.close()</code>,这样在下一次open的时候,才不会重复分配堆栈空间。</p>\\n</li>\\n<li>\\n<p><code>page.evaluate(fn, [param])</code>\\n对于page打开的页面,往往需要与其进行一些交互。<code>page.evaluate()</code>提供了在page打开页面的上下文(下文直接用page上下文指代)执行function的功能(类比Chrome开发者工具的控制台)。如下例:</p>\\n<div class=\\\"gatsby-highlight\\\">\\n <pre class=\\\"language-js\\\"><code>page<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">open</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">'http://m.bing.com'</span><span class=\\\"token punctuation\\\">,</span> <span class=\\\"token keyword\\\">function</span><span class=\\\"token punctuation\\\">(</span>status<span class=\\\"token punctuation\\\">)</span> <span class=\\\"token punctuation\\\">{</span>\\n <span class=\\\"token keyword\\\">var</span> title <span class=\\\"token operator\\\">=</span> page<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">evaluate</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token keyword\\\">function</span><span class=\\\"token punctuation\\\">(</span>s<span class=\\\"token punctuation\\\">)</span> <span class=\\\"token punctuation\\\">{</span>\\n <span class=\\\"token keyword\\\">return</span> document<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">querySelector</span><span class=\\\"token punctuation\\\">(</span>s<span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">.</span>innerText<span class=\\\"token punctuation\\\">;</span>\\n <span class=\\\"token punctuation\\\">}</span><span class=\\\"token punctuation\\\">,</span> <span class=\\\"token string\\\">'title'</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n console<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">log</span><span class=\\\"token punctuation\\\">(</span>title<span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n phantom<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">exit</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n<span class=\\\"token punctuation\\\">}</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n</code></pre>\\n </div>\\n<p>在这个例子中,<code>page.evaluate()</code>接受两个参数,第一个是必需的,表示需要在page上下文运行的函数<code>fn</code>;第二个是可选的,表示需要传给<code>fn</code>的参数<code>param</code>。<code>fn</code>允许有一个返回值<code>return</code>,并且此返回值最终作为<code>page.evaluate()</code>的返回值。这边对于刚刚命名的<code>param</code>和<code>return</code>有一些额外的说明和注意事项。对于整个phantom进程而言,<code>page.evaluate()</code>是跑在一个沙盒中,<code>fn</code>无法访问一切phantom域中的变量;同样<code>page.evaluate()</code>方法外部也不应该尝试访问page上下文中的内容。那么如果两个作用域需要交换一些数据,只能依靠<code>param</code>和<code>return</code>。不过限制很大,<code>param</code>和<code>return</code>必须为能够转化为JSON字符串,换言之,只能是基本数据类型或者简单对象,像DOM 节点、$对象、function、闭包等就无能为力了。\\n这个方法是同步的,如果执行的内容对后续操作不具备前置性,可以尝试异步方法以提高性能:<code>page.evaluateAsync()</code>。</p>\\n</li>\\n<li>\\n<p><code>page.render(filename)</code>\\n<code>page.render()</code>能够把当前页面渲染成图片并输出到指定文件中。输出的文件格式由传入的文件扩展名决定,目前支持<code>PNG</code>、<code>JPEG</code>、<code>GIF</code>、<code>PDF</code>。</p>\\n<div class=\\\"gatsby-highlight\\\">\\n <pre class=\\\"language-js\\\"><code><span class=\\\"token keyword\\\">var</span> page <span class=\\\"token operator\\\">=</span> <span class=\\\"token function\\\">require</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">'webpage'</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">create</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\npage<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">open</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">'http://github.com/'</span><span class=\\\"token punctuation\\\">,</span> <span class=\\\"token keyword\\\">function</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token punctuation\\\">)</span> <span class=\\\"token punctuation\\\">{</span>\\n page<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">render</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">'github.png'</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n phantom<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">exit</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n<span class=\\\"token punctuation\\\">}</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n</code></pre>\\n </div>\\n<p>还有其他一些API会对<code>page.render()</code>产生影响,如:</p>\\n<ul>\\n<li><code>page.zoomFactor</code> Number: 设置缩放比率</li>\\n<li>\\n<p><code>page.clipRect</code> Object:设置输出的矩形区域,例如:</p>\\n<div class=\\\"gatsby-highlight\\\">\\n <pre class=\\\"language-js\\\"><code>page<span class=\\\"token punctuation\\\">.</span>clipRect <span class=\\\"token operator\\\">=</span> <span class=\\\"token punctuation\\\">{</span>\\n top<span class=\\\"token punctuation\\\">:</span> <span class=\\\"token number\\\">14</span><span class=\\\"token punctuation\\\">,</span>\\n left<span class=\\\"token punctuation\\\">:</span> <span class=\\\"token number\\\">3</span><span class=\\\"token punctuation\\\">,</span>\\n width<span class=\\\"token punctuation\\\">:</span> <span class=\\\"token number\\\">400</span><span class=\\\"token punctuation\\\">,</span>\\n height<span class=\\\"token punctuation\\\">:</span> <span class=\\\"token number\\\">300</span>\\n<span class=\\\"token punctuation\\\">}</span><span class=\\\"token punctuation\\\">;</span>\\n</code></pre>\\n </div>\\n<p>还有一些页面设置参数,如果纸张大小,侧边距等,在此不详述。web page也支持输出图片base64格式的字符串,API为<code>page.renderBase64()</code>,也不再详述。</p>\\n</li>\\n</ul>\\n</li>\\n<li>\\n<p><code>page.sendEvent()</code>\\n为了交互的需要(测试的需要),phantom允许通过代码模拟一些交互事件(注意与DOM事件的区分)。</p>\\n<ul>\\n<li>鼠标事件:\\nAPI:<code>sendEvent(mouseEventType[, mouseX, mouseY, button='left'])</code>\\n<code>mouseEventtype</code>可能的取值为:<code>'mouseup'</code>、<code>'mousedown'</code>、<code>'mousemove'</code>、<code>'doubleclick'</code>和<code>'click'</code>,这个参数为必须的。\\n后两个参数为鼠标事件的坐标位置。最后一个参数为鼠标按键,只对需要按键的事件有效,默认为<code>'left'</code>,可能值为<code>'right'</code>、<code>'left'</code>、<code>'middle'</code>。</li>\\n<li>\\n<p>键盘事件:\\nAPI:<code>sendEvent(keyboardEventType, keyOrKeys, [null, null, modifier])</code>\\n<code>keyboardEventType</code>可能的取值为<code>'keyup'</code>、<code>'keydown'</code>、<code>'keypress'</code>,第2个参数传入一个键值或一个字符串。键值可以通过<a href=\\\"https://github.com/ariya/phantomjs/commit/cab2635e66d74b7e665c44400b8b20a8f225153a\\\"><code>page.event.key</code></a>来查询调用。第三和第四个参数无效,第五个参数表示同时按下的修饰键。取值情况如下:</p>\\n<ul>\\n<li><code>0</code>: 未使用修饰键</li>\\n<li><code>0x02000000</code>: Shift键被按下</li>\\n<li><code>0x04000000</code>: Ctrl键被按下</li>\\n<li><code>0x08000000</code>: Alt键被按下\\n看一个示例:<code>page.sendEvent('keypress', page.event.key.A, null, null, 0x02000000 | 0x08000000);</code></li>\\n</ul>\\n</li>\\n</ul>\\n</li>\\n<li>\\n<p><code>page.switchToFrame(frameName/framePosition)</code>\\n默认page对应的是frame,如果一个页面中还有其他frame,则可以通过此方法切换page对应的frame。其他类似的方法还有<code>switchToChildFrame()</code>、<code>switchToParentFrame()</code>、<code>switchToFocusedFrame()</code>、<code>switchToMainFrame()</code>等,不再赘述。</p>\\n</li>\\n<li>\\n<p><code>page.uploadFile(selector, file)</code>\\n页面中常常会有上传文件的操作,但phantom没有界面,因而也就没有办法选择文件上传,通过此方法可以模拟文件上传操作。示例如下:</p>\\n<div class=\\\"gatsby-highlight\\\">\\n <pre class=\\\"language-js\\\"><code>page<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">uploadFile</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">'input[name=image]'</span><span class=\\\"token punctuation\\\">,</span> <span class=\\\"token string\\\">'/path/to/some/photo.jpg'</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n</code></pre>\\n </div>\\n</li>\\n<li>\\n<p>一些事件处理接口</p>\\n<ul>\\n<li><code>page.onAlert</code>:phantom没有界面,所以也就不能处理alert窗口,但可以通过此接口捕获到alert。</li>\\n<li><code>page.onPrompt</code>:类似的,phantom不能处理prompt窗口,通过这个接口可以捕获prompt。</li>\\n<li><code>page.onConfirm</code>:类似的,phantom不能处理confirm窗口,通过这个接口可以捕获confirm。</li>\\n<li>\\n<p><code>page.onConsoleMessage</code>:类似的,phantom不能显示console窗口,通过这个接口可以捕获console消息。</p>\\n<div class=\\\"gatsby-highlight\\\">\\n <pre class=\\\"language-js\\\"><code><span class=\\\"token keyword\\\">var</span> webPage <span class=\\\"token operator\\\">=</span> <span class=\\\"token function\\\">require</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">'webpage'</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n<span class=\\\"token keyword\\\">var</span> page <span class=\\\"token operator\\\">=</span> webPage<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">create</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\npage<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function-variable function\\\">onAlert</span> <span class=\\\"token operator\\\">=</span> <span class=\\\"token keyword\\\">function</span><span class=\\\"token punctuation\\\">(</span>msg<span class=\\\"token punctuation\\\">)</span> <span class=\\\"token punctuation\\\">{</span>\\n console<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">log</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">'ALERT: '</span> <span class=\\\"token operator\\\">+</span> msg<span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n<span class=\\\"token punctuation\\\">}</span><span class=\\\"token punctuation\\\">;</span>\\npage<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function-variable function\\\">onPrompt</span> <span class=\\\"token operator\\\">=</span> <span class=\\\"token keyword\\\">function</span><span class=\\\"token punctuation\\\">(</span>msg<span class=\\\"token punctuation\\\">,</span> defaultVal<span class=\\\"token punctuation\\\">)</span> <span class=\\\"token punctuation\\\">{</span>\\n <span class=\\\"token keyword\\\">if</span> <span class=\\\"token punctuation\\\">(</span>msg <span class=\\\"token operator\\\">===</span> <span class=\\\"token string\\\">\\\"What's your name?\\\"</span><span class=\\\"token punctuation\\\">)</span> <span class=\\\"token punctuation\\\">{</span>\\n <span class=\\\"token keyword\\\">return</span> <span class=\\\"token string\\\">'PhantomJS'</span><span class=\\\"token punctuation\\\">;</span>\\n <span class=\\\"token punctuation\\\">}</span>\\n <span class=\\\"token comment\\\">// 返回值就是prompt得到的值</span>\\n <span class=\\\"token keyword\\\">return</span> defaultVal<span class=\\\"token punctuation\\\">;</span>\\n<span class=\\\"token punctuation\\\">}</span><span class=\\\"token punctuation\\\">;</span>\\npage<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function-variable function\\\">onConfirm</span> <span class=\\\"token operator\\\">=</span> <span class=\\\"token keyword\\\">function</span><span class=\\\"token punctuation\\\">(</span>msg<span class=\\\"token punctuation\\\">)</span> <span class=\\\"token punctuation\\\">{</span>\\n console<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">log</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">'CONFIRM: '</span> <span class=\\\"token operator\\\">+</span> msg<span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n <span class=\\\"token comment\\\">// 返回true相当于点击“确定”,返回false相当于点击“取消”</span>\\n <span class=\\\"token keyword\\\">return</span> <span class=\\\"token boolean\\\">true</span><span class=\\\"token punctuation\\\">;</span>\\n<span class=\\\"token punctuation\\\">}</span><span class=\\\"token punctuation\\\">;</span>\\npage<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function-variable function\\\">onConsoleMessage</span> <span class=\\\"token operator\\\">=</span> <span class=\\\"token keyword\\\">function</span><span class=\\\"token punctuation\\\">(</span>msg<span class=\\\"token punctuation\\\">,</span> lineNum<span class=\\\"token punctuation\\\">,</span> sourceId<span class=\\\"token punctuation\\\">)</span> <span class=\\\"token punctuation\\\">{</span>\\n console<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">log</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">'CONSOLE: '</span> <span class=\\\"token operator\\\">+</span> msg <span class=\\\"token operator\\\">+</span> <span class=\\\"token string\\\">' (from line #'</span> <span class=\\\"token operator\\\">+</span> lineNum <span class=\\\"token operator\\\">+</span> <span class=\\\"token string\\\">' in \\\"'</span> <span class=\\\"token operator\\\">+</span> sourceId <span class=\\\"token operator\\\">+</span> <span class=\\\"token string\\\">'\\\")'</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n<span class=\\\"token punctuation\\\">}</span><span class=\\\"token punctuation\\\">;</span>\\n</code></pre>\\n </div>\\n</li>\\n<li><code>page.onInitialized</code>:在page创建后触发。</li>\\n<li><code>page.onUrlChanged</code>:在url发生变化时触发。它接受新的url作为参数。首次加载页面,<code>page.onUrlChanged</code>是在<code>page.onInitialized</code>之后触发。</li>\\n<li>\\n<p><code>page.onNavigationRequested</code>:如果在<code>page.navigationLocked</code>中允许页面跳转,此接口才会有意义(参见<code>page.navigationLocked</code>)。它接受4个参数,先看示例:</p>\\n<div class=\\\"gatsby-highlight\\\">\\n <pre class=\\\"language-js\\\"><code>page<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function-variable function\\\">onNavigationRequested</span> <span class=\\\"token operator\\\">=</span> <span class=\\\"token keyword\\\">function</span><span class=\\\"token punctuation\\\">(</span>url<span class=\\\"token punctuation\\\">,</span> type<span class=\\\"token punctuation\\\">,</span> willNavigate<span class=\\\"token punctuation\\\">,</span> main<span class=\\\"token punctuation\\\">)</span> <span class=\\\"token punctuation\\\">{</span>\\n console<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">log</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">'Trying to navigate to: '</span> <span class=\\\"token operator\\\">+</span> url<span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n console<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">log</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">'Caused by: '</span> <span class=\\\"token operator\\\">+</span> type<span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n console<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">log</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">'Will actually navigate: '</span> <span class=\\\"token operator\\\">+</span> willNavigate<span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n console<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">log</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">'Sent from the page\\\\'s main frame: '</span> <span class=\\\"token operator\\\">+</span> main<span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n<span class=\\\"token punctuation\\\">}</span>\\n</code></pre>\\n </div>\\n<ul>\\n<li><code>url</code>表示要跳转到的url</li>\\n<li><code>type</code>表示产生跳转的原因,可能值有<code>'Undefined'</code>、<code>'LinkClicked'</code>、<code>'FormSubmitted'</code>、<code>'BackOrForward'</code>、<code>'Reload'</code>、<code>'FormResubmitted'</code>、<code>'Other'</code></li>\\n<li><code>willNavigate</code>表示是否会跳转,由<code>page.navigationLocked</code>控制</li>\\n<li><code>main</code>表示发生跳转的是否是主frame,如果是主frame则为true,如果为其他frame则为false</li>\\n</ul>\\n</li>\\n<li><code>page.onLoadStarted</code>:在开始载入资源时触发。</li>\\n<li><code>page.onLoadFinished</code>:页面所有资源载入完成后触发。其实与<code>page.open()</code>的回调函数等价。它接受一个参数<code>status</code>,表示加载是否成功。参见<code>page.open()</code>。</li>\\n<li><code>page.onClosing</code>:当在phantom域调用<code>page.close()</code>或page上下文调用<code>window.close()</code>时触发。</li>\\n<li><code>page.onError</code>: 此接口捕获所有page上下文发生的javascript错误。参数是错误信息和调用堆栈,参见<code>phantom.onError</code>。如果page不处理错误,那么这些错误会冒泡到phantom的onError处理器。</li>\\n<li><code>page.onCreate</code>:当page创建子窗口时触发,例如在page上下文中使用<code>window.open</code>,但是子窗口再创建子窗口不会触发此事件。</li>\\n<li>\\n<p><code>page.onResourceRequested</code>:当页面请求一个资源时触发的事件,它接受两个参数,第一个参数是<code>requestData</code>对象,它有如下属性:</p>\\n<ul>\\n<li><code>id</code> : 资源请求编号</li>\\n<li><code>method</code> : http请求方法,get/post等</li>\\n<li><code>url</code>:请求的URL</li>\\n<li><code>time</code> : 一个Date object,包含响应接收的时间</li>\\n<li><code>headers</code> : http头部的信息列表\\n第二个参数是<code>networkRequest</code>实例,它包含3个方法:</li>\\n<li><code>abort()</code>:中断当前的请求。这样做会触发onResourceError</li>\\n<li><code>changeUrl(url)</code>:改变当前请求的目标url</li>\\n<li><code>setHeader(key, value)</code>:修改/添加http头部信息</li>\\n</ul>\\n</li>\\n<li>\\n<p><code>page.onResourceReceived</code>:当一个资源请求的响应接收到后触发此事件,它接受一个<code>response</code>对象,这个对象有如下属性:</p>\\n<ul>\\n<li><code>id</code> : 资源请求编号</li>\\n<li><code>url</code>:请求的URL</li>\\n<li><code>time</code> : 一个Date object,包含响应接收的时间</li>\\n<li><code>headers</code> : http头部的信息列表</li>\\n<li><code>bodySize</code> : 已接收到的数据大小(全部数据或已接收的部分数据)</li>\\n<li><code>contentType</code> : 指定的内容类型</li>\\n<li><code>redirectURL</code> : 如果是一个重定向响应,那么此处是重定向到的url</li>\\n<li><code>stage</code> : “start”/ “end”</li>\\n<li><code>status</code> : http状态码,如:200</li>\\n<li><code>statusText</code> : http状态描述,如:OK</li>\\n</ul>\\n</li>\\n<li>\\n<p><code>page.onResourceError</code>:当资源加载失败时,触发此事件。它接收一个<code>resourceError</code>对象,这个对象有如下属性:</p>\\n<ul>\\n<li><code>id</code>:资源请求的编号</li>\\n<li><code>url</code>:请求的URL</li>\\n<li><code>errorCode</code>:错误代码</li>\\n<li>\\n<p><code>errorString</code>:错误信息\\n可参考如下示例:</p>\\n<div class=\\\"gatsby-highlight\\\">\\n <pre class=\\\"language-js\\\"><code>page<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function-variable function\\\">onResourceError</span> <span class=\\\"token operator\\\">=</span> <span class=\\\"token keyword\\\">function</span><span class=\\\"token punctuation\\\">(</span>resourceError<span class=\\\"token punctuation\\\">)</span> <span class=\\\"token punctuation\\\">{</span>\\nconsole<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">log</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">'Unable to load resource (#'</span> <span class=\\\"token operator\\\">+</span> resourceError<span class=\\\"token punctuation\\\">.</span>id <span class=\\\"token operator\\\">+</span> <span class=\\\"token string\\\">'URL:'</span> <span class=\\\"token operator\\\">+</span> resourceError<span class=\\\"token punctuation\\\">.</span>url <span class=\\\"token operator\\\">+</span> <span class=\\\"token string\\\">')'</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\nconsole<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">log</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">'Error code: '</span> <span class=\\\"token operator\\\">+</span> resourceError<span class=\\\"token punctuation\\\">.</span>errorCode <span class=\\\"token operator\\\">+</span> <span class=\\\"token string\\\">'. Description: '</span> <span class=\\\"token operator\\\">+</span> resourceError<span class=\\\"token punctuation\\\">.</span>errorString<span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n<span class=\\\"token punctuation\\\">}</span><span class=\\\"token punctuation\\\">;</span>\\n</code></pre>\\n </div>\\n</li>\\n</ul>\\n</li>\\n<li>\\n<p><code>page.onResourceTimeout</code>:在讲<code>page.settings</code>时曾经提到过这个事件。如果设置了<code>page.settings.resourceTimeout</code>,并且资源在这个时间内没有载入完成,则会触发此事件,它接受一个<code>request</code>对象,这个对象包含如下属性:</p>\\n<ul>\\n<li><code>id</code> : 资源请求编号</li>\\n<li><code>method</code> : http请求方法,get/post等</li>\\n<li><code>url</code>:请求的URL</li>\\n<li><code>time</code> : 一个Date object,包含响应接收的时间</li>\\n<li><code>headers</code> : http头部的信息列表</li>\\n<li><code>errorCode</code>:错误代码</li>\\n<li><code>errorString</code>:错误信息</li>\\n</ul>\\n</li>\\n</ul>\\n</li>\\n</ol>\\n<hr>\\n<h3>Child Process模块</h3>\\n<p>通过Child Process模块,我们能创建子进程,借助<code>stdin</code>、<code>stdout</code>、<code>stderr</code>来实现进程间通信(很C++)。使用子进程能够做很多事情,如打印、发邮件、调用脚本或其他程序(不局限于javascript)。</p>\\n<p>要使用Child Process模块,我们需要在代码中添加<code>require('child_process')</code>。</p>\\n<blockquote>\\n<p>以下内容缺乏文档支持,并未经过充分测试,可能存在一定的理解偏差。这部分功能是极有用的,希望在项目中使用的时候注意测试。</p>\\n</blockquote>\\n<blockquote>\\n<p>Child Process模块本身应该也并完全开发完全。<code>spawn()</code>、<code>execFile()</code>可用,<code>exec()</code>和<code>fork()</code>尚未实现。</p>\\n</blockquote>\\n<ol>\\n<li>\\n<p><code>spawn(command, [args], [options])</code>\\n最基本的创建进程的方法。前两个参数比较重要,例如现在想从phantom进程中运行一段Node.js脚本,脚本路径为<code>main.js</code>,这个脚本接受一个参数,假定为<code>helloworld</code>,那么如果想得到这段脚本的运行结果应该怎么做呢?参考下面的脚本:</p>\\n<div class=\\\"gatsby-highlight\\\">\\n <pre class=\\\"language-js\\\"><code><span class=\\\"token keyword\\\">var</span> spawn <span class=\\\"token operator\\\">=</span> <span class=\\\"token function\\\">require</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">\\\"child_process\\\"</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">.</span>spawn<span class=\\\"token punctuation\\\">;</span>\\nchild <span class=\\\"token operator\\\">=</span> <span class=\\\"token function\\\">spawn</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">'Node.js'</span><span class=\\\"token punctuation\\\">,</span> <span class=\\\"token punctuation\\\">[</span><span class=\\\"token string\\\">'main.js'</span><span class=\\\"token punctuation\\\">,</span> <span class=\\\"token string\\\">'helloworld'</span><span class=\\\"token punctuation\\\">]</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\nchild<span class=\\\"token punctuation\\\">.</span>stdout<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">on</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">\\\"data\\\"</span><span class=\\\"token punctuation\\\">,</span> <span class=\\\"token keyword\\\">function</span> <span class=\\\"token punctuation\\\">(</span>data<span class=\\\"token punctuation\\\">)</span> <span class=\\\"token punctuation\\\">{</span>\\n console<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">log</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">\\\"spawnSTDOUT:\\\"</span><span class=\\\"token punctuation\\\">,</span> JSON<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">stringify</span><span class=\\\"token punctuation\\\">(</span>data<span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">)</span>\\n<span class=\\\"token punctuation\\\">}</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\nchild<span class=\\\"token punctuation\\\">.</span>stderr<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">on</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">\\\"data\\\"</span><span class=\\\"token punctuation\\\">,</span> <span class=\\\"token keyword\\\">function</span> <span class=\\\"token punctuation\\\">(</span>data<span class=\\\"token punctuation\\\">)</span> <span class=\\\"token punctuation\\\">{</span>\\n console<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">log</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">\\\"spawnSTDERR:\\\"</span><span class=\\\"token punctuation\\\">,</span> JSON<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">stringify</span><span class=\\\"token punctuation\\\">(</span>data<span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">)</span>\\n<span class=\\\"token punctuation\\\">}</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\nchild<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">on</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">\\\"exit\\\"</span><span class=\\\"token punctuation\\\">,</span> <span class=\\\"token keyword\\\">function</span> <span class=\\\"token punctuation\\\">(</span>code<span class=\\\"token punctuation\\\">)</span> <span class=\\\"token punctuation\\\">{</span>\\n console<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">log</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">\\\"spawnEXIT:\\\"</span><span class=\\\"token punctuation\\\">,</span> code<span class=\\\"token punctuation\\\">)</span>\\n<span class=\\\"token punctuation\\\">}</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n<span class=\\\"token function\\\">setTimeout</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token keyword\\\">function</span> <span class=\\\"token punctuation\\\">(</span><span class=\\\"token punctuation\\\">)</span> <span class=\\\"token punctuation\\\">{</span>\\n phantom<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">exit</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token number\\\">0</span><span class=\\\"token punctuation\\\">)</span>\\n<span class=\\\"token punctuation\\\">}</span><span class=\\\"token punctuation\\\">,</span> <span class=\\\"token number\\\">2000</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n</code></pre>\\n </div>\\n<p>其实<code>spawn()</code>方法没什么神秘的,它就是运行第一个参数表示的命令,第二个参数就是这个命令的参数列表。所以如果要开启一个新的phantom进程,第一个参数为<code>phantom</code>就行。同样的道理,指定好程序的路径或者是脚本语言解释器的路径,通过这个方法可以做的事情很多。\\n比较不方便的是,进程间的通信只能通过<code>stdin</code>、<code>stdout</code>、<code>stderr</code>来完成,调用<code>spawn()</code>方法后,还需要对这些交互信息进行监听,上面的例子中演示了监听<code>stdout</code>和<code>stderr</code>的方法。</p>\\n</li>\\n<li>\\n<p><code>execFile(cmd, args, opts, cb)</code>\\n就像刚刚说的,<code>spawn()</code>方法稍微感觉有点麻烦,使用<code>execFile()</code>能够稍稍简化上面的代码。<code>execFile()</code>的前三个参数与<code>spawn()</code>的三个参数完全一样,不同的是它多了一个<code>cb</code>回调函数,看一个例子就知道这个回调函数有什么用了:</p>\\n<div class=\\\"gatsby-highlight\\\">\\n <pre class=\\\"language-js\\\"><code><span class=\\\"token keyword\\\">var</span> execFile <span class=\\\"token operator\\\">=</span> <span class=\\\"token function\\\">require</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">\\\"child_process\\\"</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">.</span>execFile<span class=\\\"token punctuation\\\">;</span>\\nchild <span class=\\\"token operator\\\">=</span> <span class=\\\"token function\\\">execFile</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">'Node.js'</span><span class=\\\"token punctuation\\\">,</span> <span class=\\\"token punctuation\\\">[</span><span class=\\\"token string\\\">'main.js'</span><span class=\\\"token punctuation\\\">,</span> <span class=\\\"token string\\\">'helloworld'</span><span class=\\\"token punctuation\\\">]</span><span class=\\\"token punctuation\\\">,</span> <span class=\\\"token keyword\\\">null</span><span class=\\\"token punctuation\\\">,</span>\\n <span class=\\\"token keyword\\\">function</span> <span class=\\\"token punctuation\\\">(</span>err<span class=\\\"token punctuation\\\">,</span> stdout<span class=\\\"token punctuation\\\">,</span> stderr<span class=\\\"token punctuation\\\">)</span> <span class=\\\"token punctuation\\\">{</span>\\n console<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">log</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">\\\"execFileSTDOUT:\\\"</span><span class=\\\"token punctuation\\\">,</span> JSON<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">stringify</span><span class=\\\"token punctuation\\\">(</span>stdout<span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">)</span>\\n console<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">log</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">\\\"execFileSTDERR:\\\"</span><span class=\\\"token punctuation\\\">,</span> JSON<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">stringify</span><span class=\\\"token punctuation\\\">(</span>stderr<span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">)</span>\\n <span class=\\\"token punctuation\\\">}</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n<span class=\\\"token function\\\">setTimeout</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token keyword\\\">function</span> <span class=\\\"token punctuation\\\">(</span><span class=\\\"token punctuation\\\">)</span> <span class=\\\"token punctuation\\\">{</span>\\n phantom<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">exit</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token number\\\">0</span><span class=\\\"token punctuation\\\">)</span>\\n<span class=\\\"token punctuation\\\">}</span><span class=\\\"token punctuation\\\">,</span> <span class=\\\"token number\\\">2000</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n</code></pre>\\n </div>\\n<p>在<code>execFile()</code>中,对<code>stdout</code>、<code>stderr</code>的监听做了封装,简化了我们的代码,不过功能上与<code>spawn()</code>并无区别。</p>\\n</li>\\n</ol>\\n<hr>\\n<h3>file system模块</h3>\\n<p>虽然与Node.js中文件系统模块名称和调用方法(<code>require('fs')</code>)一样,但不得不说,phantom的文件系统模块总体是比较简单的,API不多但够用,API也不同于Node.js的异步回调风格,而是采用stream+同步的风格,浓浓的C++风味。在使用的时间请一定要注意与Node.js的文件系统模块做区分。</p>\\n<ol>\\n<li>\\n<p><code>fs.open(path, mode/opts)</code> File\\n<code>open()</code>方法接受两个参数,第一个参数是要打开的文件路径,第二个参数后面还会见到,这里统一说明。如果是字符串,则代表文件打开的模式,可选的有<code>'r'</code>、<code>'w'</code>、<code>'a/+'</code>、<code>'b'</code>(read时仅支持<code>'b'</code>);如果是一个对象,则表示配置项,一共有两个配置项,分别是<code>mode</code>和<code>charset</code>,<code>mode</code>就是刚刚提到的打开模式,<code>charset</code>表示文件的编码类型。参阅下面的示例:</p>\\n<div class=\\\"gatsby-highlight\\\">\\n <pre class=\\\"language-js\\\"><code><span class=\\\"token keyword\\\">var</span> fs <span class=\\\"token operator\\\">=</span> <span class=\\\"token function\\\">require</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">\\\"fs\\\"</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n<span class=\\\"token keyword\\\">var</span> file <span class=\\\"token operator\\\">=</span> fs<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">open</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">\\\"main.js\\\"</span><span class=\\\"token punctuation\\\">,</span> <span class=\\\"token string\\\">'r'</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\nconsole<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">log</span><span class=\\\"token punctuation\\\">(</span>file<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">read</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\nfile<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">close</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\nfile <span class=\\\"token operator\\\">=</span> fs<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">open</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">\\\"main.js\\\"</span><span class=\\\"token punctuation\\\">,</span> <span class=\\\"token string\\\">'a'</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\nfile<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">write</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">\\\"123\\\"</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\nfile<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">close</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n<span class=\\\"token function\\\">setTimeout</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token keyword\\\">function</span> <span class=\\\"token punctuation\\\">(</span><span class=\\\"token punctuation\\\">)</span> <span class=\\\"token punctuation\\\">{</span>\\n phantom<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">exit</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token number\\\">0</span><span class=\\\"token punctuation\\\">)</span>\\n<span class=\\\"token punctuation\\\">}</span><span class=\\\"token punctuation\\\">,</span> <span class=\\\"token number\\\">2000</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n</code></pre>\\n </div>\\n<p>对打开的文件,我们可以进行读写操作(具体使用与打开模式有关)。如果对一个文件执行了open,请别忘了在文件使用完成后,再对其执行close。</p>\\n</li>\\n<li>\\n<p><code>fs.read(path, mode/opts)</code> String\\n<code>fs.read()</code>方法对文件读取做了封装,不必关心文件的打开关闭,返回值为文件内容。</p>\\n</li>\\n<li>\\n<p><code>fs.write(path, content, mode/opts)</code>\\n<code>fs.write()</code>方法对文件写入做了封装,不必关心文件的打开关闭。</p>\\n</li>\\n<li>\\n<p>其他API:</p>\\n<ul>\\n<li><code>fs.size(path)</code> Number:获取文件大小</li>\\n<li><code>fs.copy(source, destination)</code>:复制文件</li>\\n<li><code>fs.copyTree(source, destination)</code>:复制目录树</li>\\n<li><code>fs.move(source, destination)</code>:移动文件</li>\\n<li><code>fs.moveTree(source, destination)</code>:移动目录树</li>\\n<li><code>fs.remove(file)</code>:删除文件</li>\\n<li><code>fs.removeTree(path)</code>:删除目录</li>\\n<li><code>fs.join(partialPath[])</code> String:组合路径</li>\\n<li><code>fs.split(path)</code> String[]:切割路径</li>\\n<li><code>fs.exist(path)</code> Boolean:文件或目录是否存在</li>\\n<li><code>fs.isFile(path)</code> Boolean:指定路径是否是文件</li>\\n<li><code>fs.isDirectory(path)</code> Boolean:指定路径是否是目录</li>\\n<li><code>fs.list(path)</code> String[]:获取指定目录下的文件/目录名称列表</li>\\n</ul>\\n</li>\\n</ol>\\n<hr>\\n<h3>System模块</h3>\\n<p>在文档一开始就已经提到过system模块,一开始的例子中,我们使用了system模块提供的<code>args</code>属性。现在重新来认识一下system模块。system模块主要管理着一些与运行环境有关的属性。</p>\\n<ol>\\n<li>\\n<p><code>system.args</code> String[]\\n获取运行phantomjs时传入的所有参数,这个不再赘述。</p>\\n</li>\\n<li>\\n<p><code>system.env</code> Object\\n获取当前的环境信息。包含操作系统信息、环境变量信息等等。通过下面的代码来查看一下吧:</p>\\n<div class=\\\"gatsby-highlight\\\">\\n <pre class=\\\"language-js\\\"><code><span class=\\\"token keyword\\\">var</span> system <span class=\\\"token operator\\\">=</span> <span class=\\\"token function\\\">require</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">'system'</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n<span class=\\\"token keyword\\\">var</span> env <span class=\\\"token operator\\\">=</span> system<span class=\\\"token punctuation\\\">.</span>env<span class=\\\"token punctuation\\\">;</span>\\nObject<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">keys</span><span class=\\\"token punctuation\\\">(</span>env<span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">forEach</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token keyword\\\">function</span> <span class=\\\"token punctuation\\\">(</span>key<span class=\\\"token punctuation\\\">)</span> <span class=\\\"token punctuation\\\">{</span>\\n console<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">log</span><span class=\\\"token punctuation\\\">(</span>key <span class=\\\"token operator\\\">+</span> <span class=\\\"token string\\\">'='</span> <span class=\\\"token operator\\\">+</span> env<span class=\\\"token punctuation\\\">[</span>key<span class=\\\"token punctuation\\\">]</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n<span class=\\\"token punctuation\\\">}</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n<span class=\\\"token function\\\">setTimeout</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token keyword\\\">function</span> <span class=\\\"token punctuation\\\">(</span><span class=\\\"token punctuation\\\">)</span> <span class=\\\"token punctuation\\\">{</span>\\n phantom<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">exit</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token number\\\">0</span><span class=\\\"token punctuation\\\">)</span>\\n<span class=\\\"token punctuation\\\">}</span><span class=\\\"token punctuation\\\">,</span> <span class=\\\"token number\\\">2000</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n</code></pre>\\n </div>\\n</li>\\n<li>\\n<p><code>system.os</code> Object\\n获取操作系统信息,返回一个简单对象,这个对象有3个属性:<code>architecture</code>:架构,如“32bit”;<code>name</code>:操作系统名称;<code>version</code>:操作系统版本。</p>\\n</li>\\n<li>\\n<p><code>system.pid</code> Number\\n获取当前进程的pid。</p>\\n</li>\\n<li>\\n<p><code>system.platform</code> String\\n永远返回<code>'phantomjs'</code></p>\\n</li>\\n</ol>\\n<hr>\\n<h3>Web Server模块</h3>\\n<p>phantomjs支持一个简单的web server模块,<code>require('webserver')</code>即可引入。web server模块基于<a href=\\\"https://code.google.com/p/mongoose/\\\">mongoose</a>。不过最好不要在生产环境使用这样的服务器模块,因为现阶段此模块仅允许10个并发请求。</p>\\n<p>看一个简单的例子吧:</p>\\n<div class=\\\"gatsby-highlight\\\">\\n <pre class=\\\"language-js\\\"><code><span class=\\\"token keyword\\\">var</span> webserver <span class=\\\"token operator\\\">=</span> <span class=\\\"token function\\\">require</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">'webserver'</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n<span class=\\\"token keyword\\\">var</span> server <span class=\\\"token operator\\\">=</span> webserver<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">create</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n<span class=\\\"token keyword\\\">var</span> service <span class=\\\"token operator\\\">=</span> server<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">listen</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token number\\\">8080</span><span class=\\\"token punctuation\\\">,</span> <span class=\\\"token keyword\\\">function</span><span class=\\\"token punctuation\\\">(</span>request<span class=\\\"token punctuation\\\">,</span> response<span class=\\\"token punctuation\\\">)</span> <span class=\\\"token punctuation\\\">{</span>\\n response<span class=\\\"token punctuation\\\">.</span>statusCode <span class=\\\"token operator\\\">=</span> <span class=\\\"token number\\\">200</span><span class=\\\"token punctuation\\\">;</span>\\n response<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">write</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">'&amp;lt;html&gt;&amp;lt;body&gt;Hello!&amp;lt;/body&gt;&amp;lt;/html&gt;'</span><span class=\\\"token punctuation\\\">)</span>\\n response<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">close</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n<span class=\\\"token punctuation\\\">}</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n</code></pre>\\n </div>\\n<p>首先需要创建服务器实例,然后调用<code>listen()</code>方法监听,<code>listen()</code>方法的第一个参数可以为一个端口号,也可以用<code>ip:port</code>这样的ip+port组合方式。第二个参数是处理请求的回调方法。下面描述一下<code>request</code>和<code>response</code>两个对象。</p>\\n<ul>\\n<li>\\n<p>request:</p>\\n<ul>\\n<li><code>method</code>:http请求的方法,get、post等</li>\\n<li><code>url</code>: 包含http请求URL和get请求的query string(如果有的话)</li>\\n<li><code>httpVersion</code>:当前采用的http协议的版本</li>\\n<li><code>headers</code>:所有http请求头部信息,以键值对的形式提供</li>\\n<li><code>post</code>:请求主体,仅对post和put方法的请求有效</li>\\n<li><code>postRaw</code>:如果Content-type为<code>'application/x-www-form-urlencoded'</code>(表单上传的默认值)时,post的原始信息会暂存在此属性中。</li>\\n</ul>\\n</li>\\n<li>\\n<p>response:</p>\\n<ul>\\n<li>\\n<p><code>headers</code>:以键值对的形式保存所有的HTTP请求头部的信息,在第一次调用<code>write()</code>方法前一定要设置</p>\\n</li>\\n<li>\\n<p><code>setHeader(name, value)</code>:设置或添加特定的头部信息</p>\\n</li>\\n<li>\\n<p><code>header(name)</code>:获取特定的头部信息</p>\\n</li>\\n<li>\\n<p><code>statusCode</code>:设置HTTP状态码</p>\\n</li>\\n<li>\\n<p><code>setEncoding(encoding)</code>: 标明传给<code>write()</code>的数据需要转换成什么格式,默认为UTF-8。如果数据为二进制字符串,则设置为“binary”</p>\\n</li>\\n<li>\\n<p><code>write(data)</code>:向response中发送数据块,可以多次调用</p>\\n</li>\\n<li>\\n<p><code>writeHead(statusCode, headers)</code>:向response中发送响应头部。<code>statusCode</code>是一个3位数字,表示HTTP状态码(如404)。后一个参数代码响应头部</p>\\n</li>\\n<li>\\n<p><code>close()</code>:关闭HTTP连接</p>\\n<ul>\\n<li>\\n<p>为了避免客户端检测到连接中断,记得最后再用<code>write()</code>方法发送一个空字符串(如:<code>response.write('')</code>)。</p>\\n</li>\\n<li>\\n<p><code>closeGracefully()</code>:功能与<code>close()</code>一样,不过更安全可靠,它能保证响应头部先发送,并自动在响应最后加上<code>response.write('')</code></p>\\n</li>\\n</ul>\\n</li>\\n</ul>\\n</li>\\n</ul>\",\"excerpt\":\"phantomjs实现了一个无界面的webkit浏览器。虽然没有界面,但dom渲染、js运行、网络访问、canvas/svg绘制等功能都很完备,在页面抓取、页面输出、自动化测试等方面有广泛的应用。 安装 下载phantomjs…\",\"fields\":{\"tagSlugs\":[\"/tags/node-js/\",\"/tags/phantom/\",\"/tags/phantomjs/\",\"/tags/多线程/\",\"/tags/无头测试/\"]},\"frontmatter\":{\"title\":\"phantomjs使用说明\",\"tags\":[\"Node.js\",\"phantom\",\"phantomjs\",\"多线程\",\"无头测试\"],\"date\":\"2014-03-19T22:47:40.000Z\",\"description\":null}}},\"pathContext\":{\"slug\":\"/2014/phantomjs/\"}}\n\n/***/ })\n\n});\n\n\n// WEBPACK FOOTER //\n// path---2014-phantomjs-c67660daf052a6dfd4f0.js","module.exports = {\"data\":{\"site\":{\"siteMetadata\":{\"title\":\"Step Over\",\"subtitle\":\"有趣的灵魂终会相遇\",\"copyright\":\"© All rights reserved.\",\"author\":{\"name\":\"周骅\",\"rss\":\"#\",\"email\":\"zhou--hua@163.com\",\"github\":\"zhouhua-js\"}}},\"markdownRemark\":{\"id\":\"/work/playground/zhouhua.site/src/pages/articles/2014/phantomjs.md absPath of file >>> MarkdownRemark\",\"html\":\"<p>phantomjs实现了一个无界面的webkit浏览器。虽然没有界面,但dom渲染、js运行、网络访问、canvas/svg绘制等功能都很完备,在页面抓取、页面输出、自动化测试等方面有广泛的应用。</p>\\n<h2>安装</h2>\\n<p>下载phantomjs(<a href=\\\"https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-1.9.7-windows.zip\\\">官方下载</a>,下载失败请访问<a href=\\\"http://zhouhua.qiniudn.com/work/Node.js/phantomjs.zip\\\">另一个下载点</a>)。解压到任意目录,并将包含phantomjs.exe的目录添加到系统路径。</p>\\n<p>如果要借助phantomjs进行无头测试,请参考各个测试框架的说明,或者参考phantomjs的官方文档:<a href=\\\"http://phantomjs.org/headless-testing.html\\\">http://phantomjs.org/headless-testing.html</a>。</p>\\n<h2>使用说明</h2>\\n<h3>简单示例</h3>\\n<div class=\\\"gatsby-highlight\\\">\\n <pre class=\\\"language-js test.js\\\"><code>var page = require('webpage').create(),\\n system = require('system'),\\n address;\\nif (system.args.length === 1) {\\n phantom.exit(1);\\n} else {\\n address = system.args[1];\\n page.open(address, function (status) {\\n console.log(page.content);\\n phantom.exit();\\n });\\n}</code></pre>\\n </div>\\n<p>运行:</p>\\n<div class=\\\"gatsby-highlight\\\">\\n <pre class=\\\"language-bash\\\"><code>phantomjs ./test.js http://baidu.com\\n</code></pre>\\n </div>\\n<p>这个例子简单地展示了通过phantom访问baidu.com,并输入html内容。使用方式就像使用Node.js运行js代码一样。在phantom运行时,它会向当前代码运行环境注入phantom对象。如上面代码中,通过phantom对象控制程序终结。示例中其他代码的含义以及更多深入的用法,将在下文中展开。</p>\\n<hr>\\n<h3>window对象</h3>\\n<p>在使用phantom时,我首先关注的是DOM和BOM接口。不过这不是一个问题,看了下面的代码就能了解:</p>\\n<div class=\\\"gatsby-highlight\\\">\\n <pre class=\\\"language-js test.js\\\"><code>console.log(window === this);\\nphantom.exit();</code></pre>\\n </div>\\n<p>运行:</p>\\n<div class=\\\"gatsby-highlight\\\">\\n <pre class=\\\"language-bash\\\"><code>phantomjs ./test.js\\n</code></pre>\\n </div>\\n<p>结果为<code>true</code>。也就是说,就像浏览器环境一样,我们的代码运行在window环境下,可以很方便地进行DOM方面的操作。</p>\\n<blockquote>\\n<p>注:如果使用web page模块打开页面,则请不要在此window对象下进行任何DOM相关的操作,因为这个window并不是page对象内的window。如果想要执行dom相关操作,请参阅<code>page.evaluate()</code>部分。</p>\\n</blockquote>\\n<hr>\\n<h3>phantom对象</h3>\\n<p>之前的例子中我们已经初步认识了phantom对象。它的功能是定义和控制phantom运行环境的参数和流程。关键的API有:</p>\\n<ol>\\n<li>\\n<p><code>phantom.args</code> String[]\\n获取传给本JS程序的参数,需要与<code>system.args</code>进行区分(system模块详见下文),后者表示传给phantomjs引擎的参数。例如<code>phantomjs ./test.js http://baidu.com</code>这句语句,通过<code>phantom.args</code>,我们能得到的参数列表为<code>['http://baidu.com']</code>,而通过<code>system.args</code>则得到<code>['./test.js', 'http://baidu.com']</code>这样的参数列表。差异就在于是否包含当前脚本名称。不过<code>phantom.scriptName</code>这个API提供了获取脚本名称的功能。</p>\\n</li>\\n<li>\\n<p><code>phantom.cookies</code> Object[]\\n获取或设置cookies,不过对于设置建议使用其他的API完成。同时相关的API还有:</p>\\n<ul>\\n<li><code>phantom.addCookie(Object)</code> Boolean:添加cookie值</li>\\n<li><code>phantom.deleteCookie(cookieName)</code> Boolean:删除指定Cookie值</li>\\n<li><code>phantom.clearCookies()</code>:清空所有的cookie</li>\\n<li><code>phantom.cookiesEnabled</code> Boolean:获取或设置是否支持cookie</li>\\n</ul>\\n</li>\\n<li>\\n<p><code>phantom.injectJs(fileName)</code> Boolean:\\n把指定的外部JS文件注入到当前环境。执行这个方法时,phantomjs首先会从当前目录检索此文件,如果找不到,则再到<code>phantom.libraryPath</code>指定的路径寻找。<code>phantom.libraryPath</code>这个API基本上就是为<code>phantom.injectJs()</code>服务的。</p>\\n</li>\\n<li>\\n<p><code>phantom.onError</code>\\n当页面存在js错误,且没有被<code>page.onError</code>处理,则会被此handler捕获。下面是使用此API的一个例子。由于phantom环境下代码调试很困难,了解这些错误捕获的API也许会对我们的实际使用有所帮助。</p>\\n<div class=\\\"gatsby-highlight\\\">\\n <pre class=\\\"language-js\\\"><code>phantom<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function-variable function\\\">onError</span> <span class=\\\"token operator\\\">=</span> <span class=\\\"token keyword\\\">function</span><span class=\\\"token punctuation\\\">(</span>msg<span class=\\\"token punctuation\\\">,</span> trace<span class=\\\"token punctuation\\\">)</span> <span class=\\\"token punctuation\\\">{</span>\\n <span class=\\\"token keyword\\\">var</span> msgStack <span class=\\\"token operator\\\">=</span> <span class=\\\"token punctuation\\\">[</span><span class=\\\"token string\\\">'PHANTOM ERROR: '</span> <span class=\\\"token operator\\\">+</span> msg<span class=\\\"token punctuation\\\">]</span><span class=\\\"token punctuation\\\">;</span>\\n <span class=\\\"token keyword\\\">if</span> <span class=\\\"token punctuation\\\">(</span>trace <span class=\\\"token operator\\\">&</span>amp<span class=\\\"token punctuation\\\">;</span>amp<span class=\\\"token punctuation\\\">;</span><span class=\\\"token operator\\\">&</span>amp<span class=\\\"token punctuation\\\">;</span>amp<span class=\\\"token punctuation\\\">;</span> trace<span class=\\\"token punctuation\\\">.</span>length<span class=\\\"token punctuation\\\">)</span> <span class=\\\"token punctuation\\\">{</span>\\n msgStack<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">push</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">'TRACE:'</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n trace<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">forEach</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token keyword\\\">function</span><span class=\\\"token punctuation\\\">(</span>t<span class=\\\"token punctuation\\\">)</span> <span class=\\\"token punctuation\\\">{</span>\\n msgStack<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">push</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">' -&gt; '</span> <span class=\\\"token operator\\\">+</span> <span class=\\\"token punctuation\\\">(</span>t<span class=\\\"token punctuation\\\">.</span>file <span class=\\\"token operator\\\">||</span> t<span class=\\\"token punctuation\\\">.</span>sourceURL<span class=\\\"token punctuation\\\">)</span> <span class=\\\"token operator\\\">+</span> <span class=\\\"token string\\\">': '</span> <span class=\\\"token operator\\\">+</span> t<span class=\\\"token punctuation\\\">.</span>line <span class=\\\"token operator\\\">+</span> <span class=\\\"token punctuation\\\">(</span>t<span class=\\\"token punctuation\\\">.</span><span class=\\\"token keyword\\\">function</span> <span class=\\\"token operator\\\">?</span> <span class=\\\"token string\\\">' (in function '</span> <span class=\\\"token operator\\\">+</span> t<span class=\\\"token punctuation\\\">.</span><span class=\\\"token keyword\\\">function</span> <span class=\\\"token operator\\\">+</span><span class=\\\"token string\\\">')'</span> <span class=\\\"token punctuation\\\">:</span> <span class=\\\"token string\\\">''</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n <span class=\\\"token punctuation\\\">}</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n <span class=\\\"token punctuation\\\">}</span>\\n console<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">error</span><span class=\\\"token punctuation\\\">(</span>msgStack<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">join</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">'\\\\n'</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n phantom<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">exit</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token number\\\">1</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n<span class=\\\"token punctuation\\\">}</span><span class=\\\"token punctuation\\\">;</span>\\n</code></pre>\\n </div>\\n</li>\\n<li>\\n<p><code>phantom.exit(returnValue)</code>\\n这个API已经见过多次了,它的作用是退出程序,可以设置一个退出代码,默认是0。</p>\\n</li>\\n</ol>\\n<hr>\\n<h3>web page 模块</h3>\\n<p>web page模块的功能是处理具体的页面。使用时需要引入模块,并创建实例:</p>\\n<div class=\\\"gatsby-highlight\\\">\\n <pre class=\\\"language-js\\\"><code><span class=\\\"token keyword\\\">var</span> webPage <span class=\\\"token operator\\\">=</span> <span class=\\\"token function\\\">require</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">'webpage'</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n<span class=\\\"token keyword\\\">var</span> page <span class=\\\"token operator\\\">=</span> webPage<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">create</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n</code></pre>\\n </div>\\n<blockquote>\\n<p>本文中不经说明,<code>page</code>指代<code>require(&quot;webpage&quot;).create()</code>的实例。</p>\\n</blockquote>\\n<ol>\\n<li>\\n<p><code>page.cookies</code> Object[]\\n与上文中的<code>phantom.cookies</code>类似,表示本url下的cookie的读取。同样类似的API还有<code>addCookie()</code>、<code>deleteCookie()</code>、<code>clearCookies()</code>。</p>\\n</li>\\n<li>\\n<p>页面内容相关的API</p>\\n<ul>\\n<li><code>page.content</code> String:获取或设置当前页面的html。</li>\\n<li><code>page.plainText</code> String:这是一个只读属性,获取页面去除html标记的文本(考虑<code>$.text()</code>)。</li>\\n<li><code>page.url</code> String:只读,获取当前页面的url。</li>\\n<li><code>page.setContent()</code>:允许修改<code>page.content</code>和<code>page.url</code>内容,会触发reload。</li>\\n</ul>\\n</li>\\n<li>\\n<p><code>page.settings</code> Object\\n对于当前页面的一些配置项。此API必须在<code>page.open()</code>调用之前设置,否则不会起作用。以下是配置项:</p>\\n<ul>\\n<li><code>javascriptEnabled</code> 默认<code>true</code>:是否执行页面内的javascript</li>\\n<li><code>loadImages</code> 默认<code>true</code>:是否载入图片</li>\\n<li><code>userAgent</code> :传递给服务器的userAgent字符串</li>\\n<li><code>userName</code> :用于http访问授权的用户名</li>\\n<li><code>password</code> :用于http访问授权的密码</li>\\n<li><code>XSSAuditingEnabled</code> 默认<code>false</code>:是否监控跨域请求</li>\\n<li><code>resourceTimeout</code> 单位<code>ms</code>:定义资源请求的超时时间。如果设置了此项,则页面中如果有任何资源超过此时限未请求成功,则页面其他部分也会停止请求,并触发<code>onResourceTimeout()</code>事件处理。</li>\\n</ul>\\n</li>\\n<li>\\n<p><code>page.customHeaders</code> Object\\nphantom允许在请求时在http请求头部添加额外信息,此设置项对这个page里面所有的请求都生效(包含页面和其他资源的请求)。添加的信息并没有限制,但如果设置<code>User-Agent</code>的值,那么这个值会覆盖掉<code>page.settings</code>里的设置值。示例:</p>\\n<div class=\\\"gatsby-highlight\\\">\\n <pre class=\\\"language-js\\\"><code>page<span class=\\\"token punctuation\\\">.</span>customHeaders <span class=\\\"token operator\\\">=</span> <span class=\\\"token punctuation\\\">{</span>\\n <span class=\\\"token string\\\">\\\"X-Test\\\"</span><span class=\\\"token punctuation\\\">:</span> <span class=\\\"token string\\\">\\\"foo\\\"</span><span class=\\\"token punctuation\\\">,</span>\\n <span class=\\\"token string\\\">\\\"DNT\\\"</span><span class=\\\"token punctuation\\\">:</span> <span class=\\\"token string\\\">\\\"1\\\"</span>\\n<span class=\\\"token punctuation\\\">}</span><span class=\\\"token punctuation\\\">;</span>\\n</code></pre>\\n </div>\\n</li>\\n<li>\\n<p><code>page.libraryPath</code> String\\n与<code>phantom.libraryPath</code>类似,page对象也支持设置js文件路径,同时可以通过相应的<code>page.injectJs()</code>方法注入javascript文件。除了<code>page.injectJs()</code>方法外,还有<code>page.includeJs()</code>也可以加入javascript文件。它们的区别在于,<code>page.injectJs()</code>不强求此文件能访问得到,即使是一个不可访问的资源也可以。</p>\\n</li>\\n<li>\\n<p><code>page.navigationLocked</code> Boolean 默认<code>fasle</code>\\n设置是否允许离开当前页面,默认是允许。</p>\\n</li>\\n<li>\\n<p><code>page.open()</code>\\n此方法用于打开一个网页,是一个很重要的API,它有三种调用形式:</p>\\n<ul>\\n<li><code>open(url, callback)</code></li>\\n<li><code>open(url, method, callback)</code></li>\\n<li><code>open(url, method, data, callback)</code>\\n联想一下<code>$.ajax()</code>,可以更好理解这个API。对于这些参数,需要单独阐述的是<code>callback</code>。<code>callback()</code>会在页面载入完成后调用,由<code>page.onLoadFinished</code>调用(时机晚于<code>page.onLoadFinished</code>)。这个<code>callback</code>会接受一个参数<code>status</code>,可能值为<code>'success</code>和<code>'fail'</code>,指示页面是否加载成功。示例可以参考“简单示例”一节的例子。</li>\\n</ul>\\n</li>\\n<li>\\n<p><code>page.close()</code>\\n与<code>page.open()</code>对应,调用<code>page.close()</code>之后,会释放page所占用的内存,我们不可以在此之后再调用page实例。在实际的操作中,调用此方法并不会完成清空所占内存;javascript的垃圾回收机制也不会回收page实例。但在实际使用中,常常会遇到将一个page实例反复open的情况。在一个页面用完后,记得一定要执行<code>page.close()</code>,这样在下一次open的时候,才不会重复分配堆栈空间。</p>\\n</li>\\n<li>\\n<p><code>page.evaluate(fn, [param])</code>\\n对于page打开的页面,往往需要与其进行一些交互。<code>page.evaluate()</code>提供了在page打开页面的上下文(下文直接用page上下文指代)执行function的功能(类比Chrome开发者工具的控制台)。如下例:</p>\\n<div class=\\\"gatsby-highlight\\\">\\n <pre class=\\\"language-js\\\"><code>page<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">open</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">'http://m.bing.com'</span><span class=\\\"token punctuation\\\">,</span> <span class=\\\"token keyword\\\">function</span><span class=\\\"token punctuation\\\">(</span>status<span class=\\\"token punctuation\\\">)</span> <span class=\\\"token punctuation\\\">{</span>\\n <span class=\\\"token keyword\\\">var</span> title <span class=\\\"token operator\\\">=</span> page<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">evaluate</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token keyword\\\">function</span><span class=\\\"token punctuation\\\">(</span>s<span class=\\\"token punctuation\\\">)</span> <span class=\\\"token punctuation\\\">{</span>\\n <span class=\\\"token keyword\\\">return</span> document<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">querySelector</span><span class=\\\"token punctuation\\\">(</span>s<span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">.</span>innerText<span class=\\\"token punctuation\\\">;</span>\\n <span class=\\\"token punctuation\\\">}</span><span class=\\\"token punctuation\\\">,</span> <span class=\\\"token string\\\">'title'</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n console<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">log</span><span class=\\\"token punctuation\\\">(</span>title<span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n phantom<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">exit</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n<span class=\\\"token punctuation\\\">}</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n</code></pre>\\n </div>\\n<p>在这个例子中,<code>page.evaluate()</code>接受两个参数,第一个是必需的,表示需要在page上下文运行的函数<code>fn</code>;第二个是可选的,表示需要传给<code>fn</code>的参数<code>param</code>。<code>fn</code>允许有一个返回值<code>return</code>,并且此返回值最终作为<code>page.evaluate()</code>的返回值。这边对于刚刚命名的<code>param</code>和<code>return</code>有一些额外的说明和注意事项。对于整个phantom进程而言,<code>page.evaluate()</code>是跑在一个沙盒中,<code>fn</code>无法访问一切phantom域中的变量;同样<code>page.evaluate()</code>方法外部也不应该尝试访问page上下文中的内容。那么如果两个作用域需要交换一些数据,只能依靠<code>param</code>和<code>return</code>。不过限制很大,<code>param</code>和<code>return</code>必须为能够转化为JSON字符串,换言之,只能是基本数据类型或者简单对象,像DOM 节点、$对象、function、闭包等就无能为力了。\\n这个方法是同步的,如果执行的内容对后续操作不具备前置性,可以尝试异步方法以提高性能:<code>page.evaluateAsync()</code>。</p>\\n</li>\\n<li>\\n<p><code>page.render(filename)</code>\\n<code>page.render()</code>能够把当前页面渲染成图片并输出到指定文件中。输出的文件格式由传入的文件扩展名决定,目前支持<code>PNG</code>、<code>JPEG</code>、<code>GIF</code>、<code>PDF</code>。</p>\\n<div class=\\\"gatsby-highlight\\\">\\n <pre class=\\\"language-js\\\"><code><span class=\\\"token keyword\\\">var</span> page <span class=\\\"token operator\\\">=</span> <span class=\\\"token function\\\">require</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">'webpage'</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">create</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\npage<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">open</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">'http://github.com/'</span><span class=\\\"token punctuation\\\">,</span> <span class=\\\"token keyword\\\">function</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token punctuation\\\">)</span> <span class=\\\"token punctuation\\\">{</span>\\n page<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">render</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">'github.png'</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n phantom<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">exit</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n<span class=\\\"token punctuation\\\">}</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n</code></pre>\\n </div>\\n<p>还有其他一些API会对<code>page.render()</code>产生影响,如:</p>\\n<ul>\\n<li><code>page.zoomFactor</code> Number: 设置缩放比率</li>\\n<li>\\n<p><code>page.clipRect</code> Object:设置输出的矩形区域,例如:</p>\\n<div class=\\\"gatsby-highlight\\\">\\n <pre class=\\\"language-js\\\"><code>page<span class=\\\"token punctuation\\\">.</span>clipRect <span class=\\\"token operator\\\">=</span> <span class=\\\"token punctuation\\\">{</span>\\n top<span class=\\\"token punctuation\\\">:</span> <span class=\\\"token number\\\">14</span><span class=\\\"token punctuation\\\">,</span>\\n left<span class=\\\"token punctuation\\\">:</span> <span class=\\\"token number\\\">3</span><span class=\\\"token punctuation\\\">,</span>\\n width<span class=\\\"token punctuation\\\">:</span> <span class=\\\"token number\\\">400</span><span class=\\\"token punctuation\\\">,</span>\\n height<span class=\\\"token punctuation\\\">:</span> <span class=\\\"token number\\\">300</span>\\n<span class=\\\"token punctuation\\\">}</span><span class=\\\"token punctuation\\\">;</span>\\n</code></pre>\\n </div>\\n<p>还有一些页面设置参数,如果纸张大小,侧边距等,在此不详述。web page也支持输出图片base64格式的字符串,API为<code>page.renderBase64()</code>,也不再详述。</p>\\n</li>\\n</ul>\\n</li>\\n<li>\\n<p><code>page.sendEvent()</code>\\n为了交互的需要(测试的需要),phantom允许通过代码模拟一些交互事件(注意与DOM事件的区分)。</p>\\n<ul>\\n<li>鼠标事件:\\nAPI:<code>sendEvent(mouseEventType[, mouseX, mouseY, button='left'])</code>\\n<code>mouseEventtype</code>可能的取值为:<code>'mouseup'</code>、<code>'mousedown'</code>、<code>'mousemove'</code>、<code>'doubleclick'</code>和<code>'click'</code>,这个参数为必须的。\\n后两个参数为鼠标事件的坐标位置。最后一个参数为鼠标按键,只对需要按键的事件有效,默认为<code>'left'</code>,可能值为<code>'right'</code>、<code>'left'</code>、<code>'middle'</code>。</li>\\n<li>\\n<p>键盘事件:\\nAPI:<code>sendEvent(keyboardEventType, keyOrKeys, [null, null, modifier])</code>\\n<code>keyboardEventType</code>可能的取值为<code>'keyup'</code>、<code>'keydown'</code>、<code>'keypress'</code>,第2个参数传入一个键值或一个字符串。键值可以通过<a href=\\\"https://github.com/ariya/phantomjs/commit/cab2635e66d74b7e665c44400b8b20a8f225153a\\\"><code>page.event.key</code></a>来查询调用。第三和第四个参数无效,第五个参数表示同时按下的修饰键。取值情况如下:</p>\\n<ul>\\n<li><code>0</code>: 未使用修饰键</li>\\n<li><code>0x02000000</code>: Shift键被按下</li>\\n<li><code>0x04000000</code>: Ctrl键被按下</li>\\n<li><code>0x08000000</code>: Alt键被按下\\n看一个示例:<code>page.sendEvent('keypress', page.event.key.A, null, null, 0x02000000 | 0x08000000);</code></li>\\n</ul>\\n</li>\\n</ul>\\n</li>\\n<li>\\n<p><code>page.switchToFrame(frameName/framePosition)</code>\\n默认page对应的是frame,如果一个页面中还有其他frame,则可以通过此方法切换page对应的frame。其他类似的方法还有<code>switchToChildFrame()</code>、<code>switchToParentFrame()</code>、<code>switchToFocusedFrame()</code>、<code>switchToMainFrame()</code>等,不再赘述。</p>\\n</li>\\n<li>\\n<p><code>page.uploadFile(selector, file)</code>\\n页面中常常会有上传文件的操作,但phantom没有界面,因而也就没有办法选择文件上传,通过此方法可以模拟文件上传操作。示例如下:</p>\\n<div class=\\\"gatsby-highlight\\\">\\n <pre class=\\\"language-js\\\"><code>page<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">uploadFile</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">'input[name=image]'</span><span class=\\\"token punctuation\\\">,</span> <span class=\\\"token string\\\">'/path/to/some/photo.jpg'</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n</code></pre>\\n </div>\\n</li>\\n<li>\\n<p>一些事件处理接口</p>\\n<ul>\\n<li><code>page.onAlert</code>:phantom没有界面,所以也就不能处理alert窗口,但可以通过此接口捕获到alert。</li>\\n<li><code>page.onPrompt</code>:类似的,phantom不能处理prompt窗口,通过这个接口可以捕获prompt。</li>\\n<li><code>page.onConfirm</code>:类似的,phantom不能处理confirm窗口,通过这个接口可以捕获confirm。</li>\\n<li>\\n<p><code>page.onConsoleMessage</code>:类似的,phantom不能显示console窗口,通过这个接口可以捕获console消息。</p>\\n<div class=\\\"gatsby-highlight\\\">\\n <pre class=\\\"language-js\\\"><code><span class=\\\"token keyword\\\">var</span> webPage <span class=\\\"token operator\\\">=</span> <span class=\\\"token function\\\">require</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">'webpage'</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n<span class=\\\"token keyword\\\">var</span> page <span class=\\\"token operator\\\">=</span> webPage<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">create</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\npage<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function-variable function\\\">onAlert</span> <span class=\\\"token operator\\\">=</span> <span class=\\\"token keyword\\\">function</span><span class=\\\"token punctuation\\\">(</span>msg<span class=\\\"token punctuation\\\">)</span> <span class=\\\"token punctuation\\\">{</span>\\n console<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">log</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">'ALERT: '</span> <span class=\\\"token operator\\\">+</span> msg<span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n<span class=\\\"token punctuation\\\">}</span><span class=\\\"token punctuation\\\">;</span>\\npage<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function-variable function\\\">onPrompt</span> <span class=\\\"token operator\\\">=</span> <span class=\\\"token keyword\\\">function</span><span class=\\\"token punctuation\\\">(</span>msg<span class=\\\"token punctuation\\\">,</span> defaultVal<span class=\\\"token punctuation\\\">)</span> <span class=\\\"token punctuation\\\">{</span>\\n <span class=\\\"token keyword\\\">if</span> <span class=\\\"token punctuation\\\">(</span>msg <span class=\\\"token operator\\\">===</span> <span class=\\\"token string\\\">\\\"What's your name?\\\"</span><span class=\\\"token punctuation\\\">)</span> <span class=\\\"token punctuation\\\">{</span>\\n <span class=\\\"token keyword\\\">return</span> <span class=\\\"token string\\\">'PhantomJS'</span><span class=\\\"token punctuation\\\">;</span>\\n <span class=\\\"token punctuation\\\">}</span>\\n <span class=\\\"token comment\\\">// 返回值就是prompt得到的值</span>\\n <span class=\\\"token keyword\\\">return</span> defaultVal<span class=\\\"token punctuation\\\">;</span>\\n<span class=\\\"token punctuation\\\">}</span><span class=\\\"token punctuation\\\">;</span>\\npage<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function-variable function\\\">onConfirm</span> <span class=\\\"token operator\\\">=</span> <span class=\\\"token keyword\\\">function</span><span class=\\\"token punctuation\\\">(</span>msg<span class=\\\"token punctuation\\\">)</span> <span class=\\\"token punctuation\\\">{</span>\\n console<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">log</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">'CONFIRM: '</span> <span class=\\\"token operator\\\">+</span> msg<span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n <span class=\\\"token comment\\\">// 返回true相当于点击“确定”,返回false相当于点击“取消”</span>\\n <span class=\\\"token keyword\\\">return</span> <span class=\\\"token boolean\\\">true</span><span class=\\\"token punctuation\\\">;</span>\\n<span class=\\\"token punctuation\\\">}</span><span class=\\\"token punctuation\\\">;</span>\\npage<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function-variable function\\\">onConsoleMessage</span> <span class=\\\"token operator\\\">=</span> <span class=\\\"token keyword\\\">function</span><span class=\\\"token punctuation\\\">(</span>msg<span class=\\\"token punctuation\\\">,</span> lineNum<span class=\\\"token punctuation\\\">,</span> sourceId<span class=\\\"token punctuation\\\">)</span> <span class=\\\"token punctuation\\\">{</span>\\n console<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">log</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">'CONSOLE: '</span> <span class=\\\"token operator\\\">+</span> msg <span class=\\\"token operator\\\">+</span> <span class=\\\"token string\\\">' (from line #'</span> <span class=\\\"token operator\\\">+</span> lineNum <span class=\\\"token operator\\\">+</span> <span class=\\\"token string\\\">' in \\\"'</span> <span class=\\\"token operator\\\">+</span> sourceId <span class=\\\"token operator\\\">+</span> <span class=\\\"token string\\\">'\\\")'</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n<span class=\\\"token punctuation\\\">}</span><span class=\\\"token punctuation\\\">;</span>\\n</code></pre>\\n </div>\\n</li>\\n<li><code>page.onInitialized</code>:在page创建后触发。</li>\\n<li><code>page.onUrlChanged</code>:在url发生变化时触发。它接受新的url作为参数。首次加载页面,<code>page.onUrlChanged</code>是在<code>page.onInitialized</code>之后触发。</li>\\n<li>\\n<p><code>page.onNavigationRequested</code>:如果在<code>page.navigationLocked</code>中允许页面跳转,此接口才会有意义(参见<code>page.navigationLocked</code>)。它接受4个参数,先看示例:</p>\\n<div class=\\\"gatsby-highlight\\\">\\n <pre class=\\\"language-js\\\"><code>page<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function-variable function\\\">onNavigationRequested</span> <span class=\\\"token operator\\\">=</span> <span class=\\\"token keyword\\\">function</span><span class=\\\"token punctuation\\\">(</span>url<span class=\\\"token punctuation\\\">,</span> type<span class=\\\"token punctuation\\\">,</span> willNavigate<span class=\\\"token punctuation\\\">,</span> main<span class=\\\"token punctuation\\\">)</span> <span class=\\\"token punctuation\\\">{</span>\\n console<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">log</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">'Trying to navigate to: '</span> <span class=\\\"token operator\\\">+</span> url<span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n console<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">log</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">'Caused by: '</span> <span class=\\\"token operator\\\">+</span> type<span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n console<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">log</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">'Will actually navigate: '</span> <span class=\\\"token operator\\\">+</span> willNavigate<span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n console<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">log</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">'Sent from the page\\\\'s main frame: '</span> <span class=\\\"token operator\\\">+</span> main<span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n<span class=\\\"token punctuation\\\">}</span>\\n</code></pre>\\n </div>\\n<ul>\\n<li><code>url</code>表示要跳转到的url</li>\\n<li><code>type</code>表示产生跳转的原因,可能值有<code>'Undefined'</code>、<code>'LinkClicked'</code>、<code>'FormSubmitted'</code>、<code>'BackOrForward'</code>、<code>'Reload'</code>、<code>'FormResubmitted'</code>、<code>'Other'</code></li>\\n<li><code>willNavigate</code>表示是否会跳转,由<code>page.navigationLocked</code>控制</li>\\n<li><code>main</code>表示发生跳转的是否是主frame,如果是主frame则为true,如果为其他frame则为false</li>\\n</ul>\\n</li>\\n<li><code>page.onLoadStarted</code>:在开始载入资源时触发。</li>\\n<li><code>page.onLoadFinished</code>:页面所有资源载入完成后触发。其实与<code>page.open()</code>的回调函数等价。它接受一个参数<code>status</code>,表示加载是否成功。参见<code>page.open()</code>。</li>\\n<li><code>page.onClosing</code>:当在phantom域调用<code>page.close()</code>或page上下文调用<code>window.close()</code>时触发。</li>\\n<li><code>page.onError</code>: 此接口捕获所有page上下文发生的javascript错误。参数是错误信息和调用堆栈,参见<code>phantom.onError</code>。如果page不处理错误,那么这些错误会冒泡到phantom的onError处理器。</li>\\n<li><code>page.onCreate</code>:当page创建子窗口时触发,例如在page上下文中使用<code>window.open</code>,但是子窗口再创建子窗口不会触发此事件。</li>\\n<li>\\n<p><code>page.onResourceRequested</code>:当页面请求一个资源时触发的事件,它接受两个参数,第一个参数是<code>requestData</code>对象,它有如下属性:</p>\\n<ul>\\n<li><code>id</code> : 资源请求编号</li>\\n<li><code>method</code> : http请求方法,get/post等</li>\\n<li><code>url</code>:请求的URL</li>\\n<li><code>time</code> : 一个Date object,包含响应接收的时间</li>\\n<li><code>headers</code> : http头部的信息列表\\n第二个参数是<code>networkRequest</code>实例,它包含3个方法:</li>\\n<li><code>abort()</code>:中断当前的请求。这样做会触发onResourceError</li>\\n<li><code>changeUrl(url)</code>:改变当前请求的目标url</li>\\n<li><code>setHeader(key, value)</code>:修改/添加http头部信息</li>\\n</ul>\\n</li>\\n<li>\\n<p><code>page.onResourceReceived</code>:当一个资源请求的响应接收到后触发此事件,它接受一个<code>response</code>对象,这个对象有如下属性:</p>\\n<ul>\\n<li><code>id</code> : 资源请求编号</li>\\n<li><code>url</code>:请求的URL</li>\\n<li><code>time</code> : 一个Date object,包含响应接收的时间</li>\\n<li><code>headers</code> : http头部的信息列表</li>\\n<li><code>bodySize</code> : 已接收到的数据大小(全部数据或已接收的部分数据)</li>\\n<li><code>contentType</code> : 指定的内容类型</li>\\n<li><code>redirectURL</code> : 如果是一个重定向响应,那么此处是重定向到的url</li>\\n<li><code>stage</code> : “start”/ “end”</li>\\n<li><code>status</code> : http状态码,如:200</li>\\n<li><code>statusText</code> : http状态描述,如:OK</li>\\n</ul>\\n</li>\\n<li>\\n<p><code>page.onResourceError</code>:当资源加载失败时,触发此事件。它接收一个<code>resourceError</code>对象,这个对象有如下属性:</p>\\n<ul>\\n<li><code>id</code>:资源请求的编号</li>\\n<li><code>url</code>:请求的URL</li>\\n<li><code>errorCode</code>:错误代码</li>\\n<li>\\n<p><code>errorString</code>:错误信息\\n可参考如下示例:</p>\\n<div class=\\\"gatsby-highlight\\\">\\n <pre class=\\\"language-js\\\"><code>page<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function-variable function\\\">onResourceError</span> <span class=\\\"token operator\\\">=</span> <span class=\\\"token keyword\\\">function</span><span class=\\\"token punctuation\\\">(</span>resourceError<span class=\\\"token punctuation\\\">)</span> <span class=\\\"token punctuation\\\">{</span>\\nconsole<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">log</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">'Unable to load resource (#'</span> <span class=\\\"token operator\\\">+</span> resourceError<span class=\\\"token punctuation\\\">.</span>id <span class=\\\"token operator\\\">+</span> <span class=\\\"token string\\\">'URL:'</span> <span class=\\\"token operator\\\">+</span> resourceError<span class=\\\"token punctuation\\\">.</span>url <span class=\\\"token operator\\\">+</span> <span class=\\\"token string\\\">')'</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\nconsole<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">log</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">'Error code: '</span> <span class=\\\"token operator\\\">+</span> resourceError<span class=\\\"token punctuation\\\">.</span>errorCode <span class=\\\"token operator\\\">+</span> <span class=\\\"token string\\\">'. Description: '</span> <span class=\\\"token operator\\\">+</span> resourceError<span class=\\\"token punctuation\\\">.</span>errorString<span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n<span class=\\\"token punctuation\\\">}</span><span class=\\\"token punctuation\\\">;</span>\\n</code></pre>\\n </div>\\n</li>\\n</ul>\\n</li>\\n<li>\\n<p><code>page.onResourceTimeout</code>:在讲<code>page.settings</code>时曾经提到过这个事件。如果设置了<code>page.settings.resourceTimeout</code>,并且资源在这个时间内没有载入完成,则会触发此事件,它接受一个<code>request</code>对象,这个对象包含如下属性:</p>\\n<ul>\\n<li><code>id</code> : 资源请求编号</li>\\n<li><code>method</code> : http请求方法,get/post等</li>\\n<li><code>url</code>:请求的URL</li>\\n<li><code>time</code> : 一个Date object,包含响应接收的时间</li>\\n<li><code>headers</code> : http头部的信息列表</li>\\n<li><code>errorCode</code>:错误代码</li>\\n<li><code>errorString</code>:错误信息</li>\\n</ul>\\n</li>\\n</ul>\\n</li>\\n</ol>\\n<hr>\\n<h3>Child Process模块</h3>\\n<p>通过Child Process模块,我们能创建子进程,借助<code>stdin</code>、<code>stdout</code>、<code>stderr</code>来实现进程间通信(很C++)。使用子进程能够做很多事情,如打印、发邮件、调用脚本或其他程序(不局限于javascript)。</p>\\n<p>要使用Child Process模块,我们需要在代码中添加<code>require('child_process')</code>。</p>\\n<blockquote>\\n<p>以下内容缺乏文档支持,并未经过充分测试,可能存在一定的理解偏差。这部分功能是极有用的,希望在项目中使用的时候注意测试。</p>\\n</blockquote>\\n<blockquote>\\n<p>Child Process模块本身应该也并完全开发完全。<code>spawn()</code>、<code>execFile()</code>可用,<code>exec()</code>和<code>fork()</code>尚未实现。</p>\\n</blockquote>\\n<ol>\\n<li>\\n<p><code>spawn(command, [args], [options])</code>\\n最基本的创建进程的方法。前两个参数比较重要,例如现在想从phantom进程中运行一段Node.js脚本,脚本路径为<code>main.js</code>,这个脚本接受一个参数,假定为<code>helloworld</code>,那么如果想得到这段脚本的运行结果应该怎么做呢?参考下面的脚本:</p>\\n<div class=\\\"gatsby-highlight\\\">\\n <pre class=\\\"language-js\\\"><code><span class=\\\"token keyword\\\">var</span> spawn <span class=\\\"token operator\\\">=</span> <span class=\\\"token function\\\">require</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">\\\"child_process\\\"</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">.</span>spawn<span class=\\\"token punctuation\\\">;</span>\\nchild <span class=\\\"token operator\\\">=</span> <span class=\\\"token function\\\">spawn</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">'Node.js'</span><span class=\\\"token punctuation\\\">,</span> <span class=\\\"token punctuation\\\">[</span><span class=\\\"token string\\\">'main.js'</span><span class=\\\"token punctuation\\\">,</span> <span class=\\\"token string\\\">'helloworld'</span><span class=\\\"token punctuation\\\">]</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\nchild<span class=\\\"token punctuation\\\">.</span>stdout<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">on</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">\\\"data\\\"</span><span class=\\\"token punctuation\\\">,</span> <span class=\\\"token keyword\\\">function</span> <span class=\\\"token punctuation\\\">(</span>data<span class=\\\"token punctuation\\\">)</span> <span class=\\\"token punctuation\\\">{</span>\\n console<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">log</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">\\\"spawnSTDOUT:\\\"</span><span class=\\\"token punctuation\\\">,</span> JSON<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">stringify</span><span class=\\\"token punctuation\\\">(</span>data<span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">)</span>\\n<span class=\\\"token punctuation\\\">}</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\nchild<span class=\\\"token punctuation\\\">.</span>stderr<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">on</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">\\\"data\\\"</span><span class=\\\"token punctuation\\\">,</span> <span class=\\\"token keyword\\\">function</span> <span class=\\\"token punctuation\\\">(</span>data<span class=\\\"token punctuation\\\">)</span> <span class=\\\"token punctuation\\\">{</span>\\n console<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">log</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">\\\"spawnSTDERR:\\\"</span><span class=\\\"token punctuation\\\">,</span> JSON<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">stringify</span><span class=\\\"token punctuation\\\">(</span>data<span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">)</span>\\n<span class=\\\"token punctuation\\\">}</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\nchild<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">on</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">\\\"exit\\\"</span><span class=\\\"token punctuation\\\">,</span> <span class=\\\"token keyword\\\">function</span> <span class=\\\"token punctuation\\\">(</span>code<span class=\\\"token punctuation\\\">)</span> <span class=\\\"token punctuation\\\">{</span>\\n console<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">log</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">\\\"spawnEXIT:\\\"</span><span class=\\\"token punctuation\\\">,</span> code<span class=\\\"token punctuation\\\">)</span>\\n<span class=\\\"token punctuation\\\">}</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n<span class=\\\"token function\\\">setTimeout</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token keyword\\\">function</span> <span class=\\\"token punctuation\\\">(</span><span class=\\\"token punctuation\\\">)</span> <span class=\\\"token punctuation\\\">{</span>\\n phantom<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">exit</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token number\\\">0</span><span class=\\\"token punctuation\\\">)</span>\\n<span class=\\\"token punctuation\\\">}</span><span class=\\\"token punctuation\\\">,</span> <span class=\\\"token number\\\">2000</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n</code></pre>\\n </div>\\n<p>其实<code>spawn()</code>方法没什么神秘的,它就是运行第一个参数表示的命令,第二个参数就是这个命令的参数列表。所以如果要开启一个新的phantom进程,第一个参数为<code>phantom</code>就行。同样的道理,指定好程序的路径或者是脚本语言解释器的路径,通过这个方法可以做的事情很多。\\n比较不方便的是,进程间的通信只能通过<code>stdin</code>、<code>stdout</code>、<code>stderr</code>来完成,调用<code>spawn()</code>方法后,还需要对这些交互信息进行监听,上面的例子中演示了监听<code>stdout</code>和<code>stderr</code>的方法。</p>\\n</li>\\n<li>\\n<p><code>execFile(cmd, args, opts, cb)</code>\\n就像刚刚说的,<code>spawn()</code>方法稍微感觉有点麻烦,使用<code>execFile()</code>能够稍稍简化上面的代码。<code>execFile()</code>的前三个参数与<code>spawn()</code>的三个参数完全一样,不同的是它多了一个<code>cb</code>回调函数,看一个例子就知道这个回调函数有什么用了:</p>\\n<div class=\\\"gatsby-highlight\\\">\\n <pre class=\\\"language-js\\\"><code><span class=\\\"token keyword\\\">var</span> execFile <span class=\\\"token operator\\\">=</span> <span class=\\\"token function\\\">require</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">\\\"child_process\\\"</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">.</span>execFile<span class=\\\"token punctuation\\\">;</span>\\nchild <span class=\\\"token operator\\\">=</span> <span class=\\\"token function\\\">execFile</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">'Node.js'</span><span class=\\\"token punctuation\\\">,</span> <span class=\\\"token punctuation\\\">[</span><span class=\\\"token string\\\">'main.js'</span><span class=\\\"token punctuation\\\">,</span> <span class=\\\"token string\\\">'helloworld'</span><span class=\\\"token punctuation\\\">]</span><span class=\\\"token punctuation\\\">,</span> <span class=\\\"token keyword\\\">null</span><span class=\\\"token punctuation\\\">,</span>\\n <span class=\\\"token keyword\\\">function</span> <span class=\\\"token punctuation\\\">(</span>err<span class=\\\"token punctuation\\\">,</span> stdout<span class=\\\"token punctuation\\\">,</span> stderr<span class=\\\"token punctuation\\\">)</span> <span class=\\\"token punctuation\\\">{</span>\\n console<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">log</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">\\\"execFileSTDOUT:\\\"</span><span class=\\\"token punctuation\\\">,</span> JSON<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">stringify</span><span class=\\\"token punctuation\\\">(</span>stdout<span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">)</span>\\n console<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">log</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">\\\"execFileSTDERR:\\\"</span><span class=\\\"token punctuation\\\">,</span> JSON<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">stringify</span><span class=\\\"token punctuation\\\">(</span>stderr<span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">)</span>\\n <span class=\\\"token punctuation\\\">}</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n<span class=\\\"token function\\\">setTimeout</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token keyword\\\">function</span> <span class=\\\"token punctuation\\\">(</span><span class=\\\"token punctuation\\\">)</span> <span class=\\\"token punctuation\\\">{</span>\\n phantom<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">exit</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token number\\\">0</span><span class=\\\"token punctuation\\\">)</span>\\n<span class=\\\"token punctuation\\\">}</span><span class=\\\"token punctuation\\\">,</span> <span class=\\\"token number\\\">2000</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n</code></pre>\\n </div>\\n<p>在<code>execFile()</code>中,对<code>stdout</code>、<code>stderr</code>的监听做了封装,简化了我们的代码,不过功能上与<code>spawn()</code>并无区别。</p>\\n</li>\\n</ol>\\n<hr>\\n<h3>file system模块</h3>\\n<p>虽然与Node.js中文件系统模块名称和调用方法(<code>require('fs')</code>)一样,但不得不说,phantom的文件系统模块总体是比较简单的,API不多但够用,API也不同于Node.js的异步回调风格,而是采用stream+同步的风格,浓浓的C++风味。在使用的时间请一定要注意与Node.js的文件系统模块做区分。</p>\\n<ol>\\n<li>\\n<p><code>fs.open(path, mode/opts)</code> File\\n<code>open()</code>方法接受两个参数,第一个参数是要打开的文件路径,第二个参数后面还会见到,这里统一说明。如果是字符串,则代表文件打开的模式,可选的有<code>'r'</code>、<code>'w'</code>、<code>'a/+'</code>、<code>'b'</code>(read时仅支持<code>'b'</code>);如果是一个对象,则表示配置项,一共有两个配置项,分别是<code>mode</code>和<code>charset</code>,<code>mode</code>就是刚刚提到的打开模式,<code>charset</code>表示文件的编码类型。参阅下面的示例:</p>\\n<div class=\\\"gatsby-highlight\\\">\\n <pre class=\\\"language-js\\\"><code><span class=\\\"token keyword\\\">var</span> fs <span class=\\\"token operator\\\">=</span> <span class=\\\"token function\\\">require</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">\\\"fs\\\"</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n<span class=\\\"token keyword\\\">var</span> file <span class=\\\"token operator\\\">=</span> fs<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">open</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">\\\"main.js\\\"</span><span class=\\\"token punctuation\\\">,</span> <span class=\\\"token string\\\">'r'</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\nconsole<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">log</span><span class=\\\"token punctuation\\\">(</span>file<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">read</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\nfile<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">close</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\nfile <span class=\\\"token operator\\\">=</span> fs<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">open</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">\\\"main.js\\\"</span><span class=\\\"token punctuation\\\">,</span> <span class=\\\"token string\\\">'a'</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\nfile<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">write</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">\\\"123\\\"</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\nfile<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">close</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n<span class=\\\"token function\\\">setTimeout</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token keyword\\\">function</span> <span class=\\\"token punctuation\\\">(</span><span class=\\\"token punctuation\\\">)</span> <span class=\\\"token punctuation\\\">{</span>\\n phantom<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">exit</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token number\\\">0</span><span class=\\\"token punctuation\\\">)</span>\\n<span class=\\\"token punctuation\\\">}</span><span class=\\\"token punctuation\\\">,</span> <span class=\\\"token number\\\">2000</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n</code></pre>\\n </div>\\n<p>对打开的文件,我们可以进行读写操作(具体使用与打开模式有关)。如果对一个文件执行了open,请别忘了在文件使用完成后,再对其执行close。</p>\\n</li>\\n<li>\\n<p><code>fs.read(path, mode/opts)</code> String\\n<code>fs.read()</code>方法对文件读取做了封装,不必关心文件的打开关闭,返回值为文件内容。</p>\\n</li>\\n<li>\\n<p><code>fs.write(path, content, mode/opts)</code>\\n<code>fs.write()</code>方法对文件写入做了封装,不必关心文件的打开关闭。</p>\\n</li>\\n<li>\\n<p>其他API:</p>\\n<ul>\\n<li><code>fs.size(path)</code> Number:获取文件大小</li>\\n<li><code>fs.copy(source, destination)</code>:复制文件</li>\\n<li><code>fs.copyTree(source, destination)</code>:复制目录树</li>\\n<li><code>fs.move(source, destination)</code>:移动文件</li>\\n<li><code>fs.moveTree(source, destination)</code>:移动目录树</li>\\n<li><code>fs.remove(file)</code>:删除文件</li>\\n<li><code>fs.removeTree(path)</code>:删除目录</li>\\n<li><code>fs.join(partialPath[])</code> String:组合路径</li>\\n<li><code>fs.split(path)</code> String[]:切割路径</li>\\n<li><code>fs.exist(path)</code> Boolean:文件或目录是否存在</li>\\n<li><code>fs.isFile(path)</code> Boolean:指定路径是否是文件</li>\\n<li><code>fs.isDirectory(path)</code> Boolean:指定路径是否是目录</li>\\n<li><code>fs.list(path)</code> String[]:获取指定目录下的文件/目录名称列表</li>\\n</ul>\\n</li>\\n</ol>\\n<hr>\\n<h3>System模块</h3>\\n<p>在文档一开始就已经提到过system模块,一开始的例子中,我们使用了system模块提供的<code>args</code>属性。现在重新来认识一下system模块。system模块主要管理着一些与运行环境有关的属性。</p>\\n<ol>\\n<li>\\n<p><code>system.args</code> String[]\\n获取运行phantomjs时传入的所有参数,这个不再赘述。</p>\\n</li>\\n<li>\\n<p><code>system.env</code> Object\\n获取当前的环境信息。包含操作系统信息、环境变量信息等等。通过下面的代码来查看一下吧:</p>\\n<div class=\\\"gatsby-highlight\\\">\\n <pre class=\\\"language-js\\\"><code><span class=\\\"token keyword\\\">var</span> system <span class=\\\"token operator\\\">=</span> <span class=\\\"token function\\\">require</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">'system'</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n<span class=\\\"token keyword\\\">var</span> env <span class=\\\"token operator\\\">=</span> system<span class=\\\"token punctuation\\\">.</span>env<span class=\\\"token punctuation\\\">;</span>\\nObject<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">keys</span><span class=\\\"token punctuation\\\">(</span>env<span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">forEach</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token keyword\\\">function</span> <span class=\\\"token punctuation\\\">(</span>key<span class=\\\"token punctuation\\\">)</span> <span class=\\\"token punctuation\\\">{</span>\\n console<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">log</span><span class=\\\"token punctuation\\\">(</span>key <span class=\\\"token operator\\\">+</span> <span class=\\\"token string\\\">'='</span> <span class=\\\"token operator\\\">+</span> env<span class=\\\"token punctuation\\\">[</span>key<span class=\\\"token punctuation\\\">]</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n<span class=\\\"token punctuation\\\">}</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n<span class=\\\"token function\\\">setTimeout</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token keyword\\\">function</span> <span class=\\\"token punctuation\\\">(</span><span class=\\\"token punctuation\\\">)</span> <span class=\\\"token punctuation\\\">{</span>\\n phantom<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">exit</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token number\\\">0</span><span class=\\\"token punctuation\\\">)</span>\\n<span class=\\\"token punctuation\\\">}</span><span class=\\\"token punctuation\\\">,</span> <span class=\\\"token number\\\">2000</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n</code></pre>\\n </div>\\n</li>\\n<li>\\n<p><code>system.os</code> Object\\n获取操作系统信息,返回一个简单对象,这个对象有3个属性:<code>architecture</code>:架构,如“32bit”;<code>name</code>:操作系统名称;<code>version</code>:操作系统版本。</p>\\n</li>\\n<li>\\n<p><code>system.pid</code> Number\\n获取当前进程的pid。</p>\\n</li>\\n<li>\\n<p><code>system.platform</code> String\\n永远返回<code>'phantomjs'</code></p>\\n</li>\\n</ol>\\n<hr>\\n<h3>Web Server模块</h3>\\n<p>phantomjs支持一个简单的web server模块,<code>require('webserver')</code>即可引入。web server模块基于<a href=\\\"https://code.google.com/p/mongoose/\\\">mongoose</a>。不过最好不要在生产环境使用这样的服务器模块,因为现阶段此模块仅允许10个并发请求。</p>\\n<p>看一个简单的例子吧:</p>\\n<div class=\\\"gatsby-highlight\\\">\\n <pre class=\\\"language-js\\\"><code><span class=\\\"token keyword\\\">var</span> webserver <span class=\\\"token operator\\\">=</span> <span class=\\\"token function\\\">require</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">'webserver'</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n<span class=\\\"token keyword\\\">var</span> server <span class=\\\"token operator\\\">=</span> webserver<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">create</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n<span class=\\\"token keyword\\\">var</span> service <span class=\\\"token operator\\\">=</span> server<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">listen</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token number\\\">8080</span><span class=\\\"token punctuation\\\">,</span> <span class=\\\"token keyword\\\">function</span><span class=\\\"token punctuation\\\">(</span>request<span class=\\\"token punctuation\\\">,</span> response<span class=\\\"token punctuation\\\">)</span> <span class=\\\"token punctuation\\\">{</span>\\n response<span class=\\\"token punctuation\\\">.</span>statusCode <span class=\\\"token operator\\\">=</span> <span class=\\\"token number\\\">200</span><span class=\\\"token punctuation\\\">;</span>\\n response<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">write</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token string\\\">'&amp;lt;html&gt;&amp;lt;body&gt;Hello!&amp;lt;/body&gt;&amp;lt;/html&gt;'</span><span class=\\\"token punctuation\\\">)</span>\\n response<span class=\\\"token punctuation\\\">.</span><span class=\\\"token function\\\">close</span><span class=\\\"token punctuation\\\">(</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n<span class=\\\"token punctuation\\\">}</span><span class=\\\"token punctuation\\\">)</span><span class=\\\"token punctuation\\\">;</span>\\n</code></pre>\\n </div>\\n<p>首先需要创建服务器实例,然后调用<code>listen()</code>方法监听,<code>listen()</code>方法的第一个参数可以为一个端口号,也可以用<code>ip:port</code>这样的ip+port组合方式。第二个参数是处理请求的回调方法。下面描述一下<code>request</code>和<code>response</code>两个对象。</p>\\n<ul>\\n<li>\\n<p>request:</p>\\n<ul>\\n<li><code>method</code>:http请求的方法,get、post等</li>\\n<li><code>url</code>: 包含http请求URL和get请求的query string(如果有的话)</li>\\n<li><code>httpVersion</code>:当前采用的http协议的版本</li>\\n<li><code>headers</code>:所有http请求头部信息,以键值对的形式提供</li>\\n<li><code>post</code>:请求主体,仅对post和put方法的请求有效</li>\\n<li><code>postRaw</code>:如果Content-type为<code>'application/x-www-form-urlencoded'</code>(表单上传的默认值)时,post的原始信息会暂存在此属性中。</li>\\n</ul>\\n</li>\\n<li>\\n<p>response:</p>\\n<ul>\\n<li>\\n<p><code>headers</code>:以键值对的形式保存所有的HTTP请求头部的信息,在第一次调用<code>write()</code>方法前一定要设置</p>\\n</li>\\n<li>\\n<p><code>setHeader(name, value)</code>:设置或添加特定的头部信息</p>\\n</li>\\n<li>\\n<p><code>header(name)</code>:获取特定的头部信息</p>\\n</li>\\n<li>\\n<p><code>statusCode</code>:设置HTTP状态码</p>\\n</li>\\n<li>\\n<p><code>setEncoding(encoding)</code>: 标明传给<code>write()</code>的数据需要转换成什么格式,默认为UTF-8。如果数据为二进制字符串,则设置为“binary”</p>\\n</li>\\n<li>\\n<p><code>write(data)</code>:向response中发送数据块,可以多次调用</p>\\n</li>\\n<li>\\n<p><code>writeHead(statusCode, headers)</code>:向response中发送响应头部。<code>statusCode</code>是一个3位数字,表示HTTP状态码(如404)。后一个参数代码响应头部</p>\\n</li>\\n<li>\\n<p><code>close()</code>:关闭HTTP连接</p>\\n<ul>\\n<li>\\n<p>为了避免客户端检测到连接中断,记得最后再用<code>write()</code>方法发送一个空字符串(如:<code>response.write('')</code>)。</p>\\n</li>\\n<li>\\n<p><code>closeGracefully()</code>:功能与<code>close()</code>一样,不过更安全可靠,它能保证响应头部先发送,并自动在响应最后加上<code>response.write('')</code></p>\\n</li>\\n</ul>\\n</li>\\n</ul>\\n</li>\\n</ul>\",\"excerpt\":\"phantomjs实现了一个无界面的webkit浏览器。虽然没有界面,但dom渲染、js运行、网络访问、canvas/svg绘制等功能都很完备,在页面抓取、页面输出、自动化测试等方面有广泛的应用。 安装 下载phantomjs…\",\"fields\":{\"tagSlugs\":[\"/tags/node-js/\",\"/tags/phantom/\",\"/tags/phantomjs/\",\"/tags/多线程/\",\"/tags/无头测试/\"]},\"frontmatter\":{\"title\":\"phantomjs使用说明\",\"tags\":[\"Node.js\",\"phantom\",\"phantomjs\",\"多线程\",\"无头测试\"],\"date\":\"2014-03-19T22:47:40.000Z\",\"description\":null}}},\"pathContext\":{\"slug\":\"/2014/phantomjs/\"}}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/json-loader!./.cache/json/2014-phantomjs.json\n// module id = 562\n// module chunks = 81292661065823"],"sourceRoot":""}