Python爬虫利器四之PhantomJS的用法

如果页面是JS渲染的,需要有一些好用的工具来帮助我们像浏览器一样渲染JS处理的页面。

其中有一个比较常用的工具,那就是PhantomJS

PhantomJS是一个无界面的,可脚本编程的WebKit浏览器引擎。它原生支持多种web 标准:DOM 操作,CSS选择器,JSON,Canvas 以及SVG。

安装

两种,1、下载源码之后编译,2、直接下载编译好的二进制文件。

编译需要的时间太长,而且需要挺多的磁盘空间。官方推荐直接下载二进制文件:下载地址

下载源码

安装完成之后命令行输入:phantomjs -v

正常显示版本号,那么证明安装成功了。

本文介绍大部分内容来自于官方文档,博主对其进行了整理,学习更多请参考官方文档

快速开始

新建一个 js(JavaScript) 文件。helloworld.js

console.log('Hello, world!');
phantom.exit(); #终止phantom 的执行。这句话非常重要,否则程序将永远不会终止。

命令行输入

phantomjs helloworld.js

输出了 Hello,world!

页面加载

例(JavaScript):实现了页面的加载并将页面保存为一张图片。

var page = require('webpage').create();
page.open('http://cuiqingcai.com', function (status) {
    console.log("Status: " + status);
    if (status === "success") {
        page.render('example.png');
    }
    phantom.exit();
});

创建了一个webpage对象,然后加载本站点主页,判断响应状态,如果成功,那么保存截图为 example.png

以上代码命名为 pageload.js,命令行:phantomjs pageload.js

测试页面加载速度

新建文件保存为 loadspeed.js。程序判断了参数的多少,如果参数不够,那么终止运行。然后记录了打开页面的时间,请求页面之后,再纪录当前时间,二者之差就是页面加载速度。这个时间包括JS渲染的时间,当然和网速也有关。

var page = require('webpage').create(),
  system = require('system'),
  t, address;
 
if (system.args.length === 1) {
  console.log('Usage: loadspeed.js <some URL>');
  phantom.exit();
}
 
t = Date.now();
address = system.args[1];
page.open(address, function(status) {
  if (status !== 'success') {
    console.log('FAIL to load the address');
  } else {
    t = Date.now() - t;
    console.log('Loading ' + system.args[1]);
    console.log('Loading time ' + t + ' msec');
  }
  phantom.exit();
});

 

phantomjs loadspeed.js http://cuiqingcai.com

运行结果
Loading http://cuiqingcai.com
Loading time 11678 msec

代码评估

用 evaluate 方法可以获取网页的源代码。这个执行是“沙盒式”的,它不会去执行网页外的 JavaScript 代码。evalute 方法可以返回一个对象,然而返回值仅限于对象,不能包含函数(或闭包)

var url = 'http://www.baidu.com';
var page = require('webpage').create();
page.open(url, function(status) {
  var title = page.evaluate(function() {
    return document.title;
  });
  console.log('Page title is ' + title);
  phantom.exit();
});

以上代码获取了百度的网站标题。

Page title is 百度一下,你就知道

任何来自于网页并且包括来自 evaluate() 内部代码的控制台信息,默认不会显示。

需要重写这个行为,使用 onConsoleMessage 回调函数,示例可以改写成

var url = 'http://www.baidu.com';
var page = require('webpage').create();
page.onConsoleMessage = function (msg) {
    console.log(msg);
};
page.open(url, function (status) {
    page.evaluate(function () {
        console.log(document.title);
    });
    phantom.exit();
});

这样的话,如果你用浏览器打开百度首页,打开调试工具的console,可以看到控制台输出信息。

重写了 onConsoleMessage 方法之后,可以发现控制台输出的结果和我们需要输出的标题都打印出来了。

一张网页,要经历怎样的过程,才能抵达用户面前?
一位新人,要经历怎样的成长,才能站在技术之巅?
探寻这里的秘密;
体验这里的挑战;
成为这里的主人;
加入百度,加入网页搜索,你,可以影响世界。
 
请将简历发送至 %c ps_recruiter@baidu.com( 邮件标题请以“姓名-应聘XX职位-来自console”命名) color:red
职位介绍:http://dwz.cn/hr2013
百度一下,你就知道

屏幕捕获

因为 PhantomJS 使用了 WebKit内核,是一个真正的布局和渲染引擎,它可以像屏幕截图一样捕获一个web界面。因为它可以渲染网页中的人和元素,所以它不仅用到HTML,CSS的内容转化,还用在SVG,Canvas。可见其功能是相当强大的。

除了 png 格式的转换,PhantomJS还支持 jpg,gif,pdf等格式。

其中最重要的方法便是 viewportSize 和 clipRect 属性。

viewportSize 是视区的大小,你可以理解为你打开了一个浏览器,然后把浏览器窗口拖到了多大。

clipRect 是裁切矩形的大小,需要四个参数,前两个是基准点,后两个参数是宽高。

相当于把浏览器窗口拖到了 1024×768 大小,然后从左上角裁切出了 1024×768 的页面。

var page = require('webpage').create();
//viewportSize being the actual size of the headless browser
page.viewportSize = { width: 1024, height: 768 };
//the clipRect is the portion of the page you are taking a screenshot of
page.clipRect = { top: 0, left: 0, width: 1024, height: 768 };
//the rest of the code is the same as the previous example
page.open('http://cuiqingcai.com/', function() {
  page.render('germy.png');
  phantom.exit();
});

 

网络监听

因为 PhantomJS 有网络通信的检查功能,它也很适合用来做网络行为的分析。

当接受到请求时,可以通过改写onResourceRequested和onResourceReceived回调函数来实现接收到资源请求和资源接受完毕的监听。

var url = 'http://www.cuiqingcai.com';
var page = require('webpage').create();
page.onResourceRequested = function(request) {
  console.log('Request ' + JSON.stringify(request, undefined, 4));
};
page.onResourceReceived = function(response) {
  console.log('Receive ' + JSON.stringify(response, undefined, 4));
};
page.open(url);

运行结果会打印出所有资源的请求和接收状态,以JSON格式输出。

页面自动化处理

PhantomJS 可以加载和操作一个web页面,所以用来自动化处理也是非常适合的。

DOM操作

脚本都是在浏览器中运行的,所以标准的 JavaScript 的 DOM 操作和 CSS 选择器也是生效的。

例如下面的例子就修改了 User-Agent,然后还返回了页面中某元素的内容。

var page = require('webpage').create();
console.log('The default user agent is ' + page.settings.userAgent);
page.settings.userAgent = 'SpecialAgent';
page.open('http://www.httpuseragent.org', function(status) {
  if (status !== 'success') {
    console.log('Unable to access network');
  } else {
    var ua = page.evaluate(function() {
      return document.getElementById('myagent').textContent;
    });
    console.log(ua);
  }
  phantom.exit();
});

#运行结果
The default user agent is Mozilla/5.0 (Macintosh; Intel Mac OS X) AppleWebKit/538.1 (KHTML, like Gecko) PhantomJS/2.1.0 Safari/538.1
Your Http User Agent string is: SpecialAgent

首先打印出了默认的 User-Agent,然后通过修改它,请求验证 User-Agent 的一个站点,通过选择器得到了修改后的 User-Agent。

使用附加库

在1.6版本之后允许添加外部的JS库,比如下面的例子添加了jQuery,然后执行了jQuery代码。引用了 jQuery 之后,我们便可以在下面写一些 jQuery 代码了。

var page = require('webpage').create();
page.open('http://www.sample.com', function() {
  page.includeJs("http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js", function() {
    page.evaluate(function() {
      $("button").click();
    });
    phantom.exit()
  });
});

Webpage对象

Webpage Webpage用例:里面介绍了 webpage的所有属性,方法,回调。

命令行

PhantomJS提供的命令行选项有:

–help or -h lists all possible command-line options. Halts immediately, will not run a script passed as argument. [帮助列表]

–version or -v prints out the version of PhantomJS. Halts immediately, will not run a script passed as argument. [查看版本]

–cookies-file=/path/to/cookies.txt specifies the file name to store the persistent Cookies. [指定存放cookies的路径]

–disk-cache=[true|false] enables disk cache (at desktop services cache storage location, default is false). Also accepted: [yes|no]. [硬盘缓存开关,默认为关]

–ignore-ssl-errors=[true|false] ignores SSL errors, such as expired or self-signed certificate errors (default is false). Also accepted: [yes|no]. [忽略ssl错误,默认不忽略]

–load-images=[true|false] load all inlined images (default is true). Also accepted: [yes|no]. [加载图片,默认为加载]

–local-storage-path=/some/path path to save LocalStorage content and WebSQL content. [本地存储路径,如本地文件和SQL文件等]

–local-storage-quota=number maximum size to allow for data. [本地文件最大大小]

–local-to-remote-url-access=[true|false] allows local content to access remote URL (default is false). Also accepted: [yes|no]. [是否允许远程加载文件,默认不允许]

–max-disk-cache-size=size limits the size of disk cache (in KB). [最大缓存空间]

–output-encoding=encoding sets the encoding used for terminal output (default is utf8). [默认输出编码,默认utf8]

–remote-debugger-port starts the script in a debug harness and listens on the specified port [远程调试端口]

–remote-debugger-autorun runs the script in the debugger immediately: ‘yes’ or ‘no’ (default) [在调试环境下是否立即执行脚本,默认否]

–proxy=address:port specifies the proxy server to use (e.g. –proxy=192.168.1.42:8080). [代理]

–proxy-type=[http|socks5|none] specifies the type of the proxy server (default is http). [代理类型,默认http]

–proxy-auth specifies the authentication information for the proxy, e.g. –proxy-auth=username:password). [代理认证]

–script-encoding=encoding sets the encoding used for the starting script (default is utf8). [脚本编码,默认utf8]

–ssl-protocol=[sslv3|sslv2|tlsv1|any’] sets the SSL protocol for secure connections (default is SSLv3). [SSL协议,默认SSLv3]

–ssl-certificates-path=<val> Sets the location for custom CA certificates (if none set, uses system default). [SSL证书路径,默认系统默认路径]

–web-security=[true|false] enables web security and forbids cross-domain XHR (default is true). Also accepted: [yes|no]. [是否开启安全保护和禁止异站Ajax,默认开启保护]

–webdriver starts in ‘Remote WebDriver mode’ (embedded GhostDriver): ‘[[:]]’ (default ‘127.0.0.1:8910’) [以远程WebDriver模式启动]

–webdriver-selenium-grid-hub URL to the Selenium Grid HUB: ‘URLTOHUB’ (default ‘none’) (NOTE: works only together with ‘–webdriver’) [Selenium接口]

–config=/path/to/config.json can utilize a JavaScript Object Notation (JSON) configuration file instead of passing in multiple command-line optionss [所有的命令行配置从config.json中读取]

注:JSON文件配置格式

{
  /* Same as: --ignore-ssl-errors=true */
  "ignoreSslErrors": true,
 
  /* Same as: --max-disk-cache-size=1000 */
  "maxDiskCacheSize": 1000,
 
  /* Same as: --output-encoding=utf8 */
  "outputEncoding": "utf8"
 
  /* etc. */
}
 
There are some keys that do not translate directly:
 
 * --disk-cache => diskCacheEnabled
 * --load-images => autoLoadImages
 * --local-storage-path => offlineStoragePath
 * --local-storage-quota => offlineStorageDefaultQuota
 * --local-to-remote-url-access => localToRemoteUrlAccessEnabled
 * --web-security => webSecurityEnabled

实例

官方实例

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值