PhantomJS的使用

简介:

1. 简介

phantomjs 简单来说是一个基于 WebKit 的“无头浏览器”环境。对“无头”,你可以理解成没有一个前端的 GUI 界面,所有的东西都在后台运行。

phantomjs 在“无头”界的名声,是源于从 WebKit 里得到的对 DOM / JS 的完整支持。

一个纯后台的,完整功能的浏览器,这东西就有很多可以想像的空间了 —— 抓取,测试等。

2. 安装

http://phantomjs.org/download.html

Windows 和 OS X ,官方都直接提供了二进制包。但是, Linux ,没有。

Linux 下要编译其实很容易,这个项目对于像 WebKit , Qt 这些依赖项目,代码都是直接放到源码中的,而不是用的动态连接的方式,编译的结果最后也只是一个 50M 多的可执行文件。但是麻烦的地方不在于依赖。按官方的文档, http://phantomjs.org/build.html 。

  • git 抽取的 phantomjs 项目一共有 500M 多吧, github 在国内的连接又慢得要死。所以,要快点的话可以在国外的主机上 git clone ,打包后 scp 回来。 (别忘了 git checkout 2.0 )
  • 我在 Ubuntu 12.04 下没有问题,但在 Ubuntu 14.04 下会有错误。搜索一下,提到的错误有关于 gcc 版本的,连着出来的有 WebKit 的 Bug ,也有 Qt 的 Bug 。不过提到这些的 Bug ,相应的 patch 在源码中我看是已经有了的,我也没把这些错误解决,后面我只在 12.04 下用了。
  • 在买的低配的远端主机上编译,会出错。原因好像是配置问题(只有 1G 内存),我本机( 8G 内存)的 docker 里编译是没有问题的。
  • 编译的时间嘛,我的 i3-4130 + 8G 内存,大概也要 1 个小时吧。

编译完成之后,在目录中会有一个新的 bin 目录,里面一个叫 phantomjs 的可执行文件,真是暴力。

通过 phantomjs -h 能看到支持的命令行参数。

3. 基本概念

phantomjs 这个东西,最好单纯地把它看成是一个独立的工具,虽然它要执行的目标源文件,是需要用 nodejs 来写的,但它跟 nodejs 的关系也仅此而已。

phantomjs 跟系统的 nodejs 无关,跟系统的 npm 也无关。不过 nodejs 在语法层面的东西它是没有问题的,比如 require 。

phantomjs 中也没有 nodejs 的官方模块,phantomjs 自己做的一些 API ,从文档来看,http://phantomjs.org/api/ ,只提到了 process / filesystem / system 。

既然 phantomjs 跟系统的 nodejs 无关,那么自然地想把它无缝融合进 nodejs 相关的方案中其实不那么容易的。按官方的说法与支持的态度 —— 进程间通信,这样搞随便把不同语言的问题也解决了。

之前介绍过 CEFPython 这个项目, http://www.zouyesheng.com/cefpython.html , phantomjs 在结构上跟它是类似的,只是 phantomjs 可以“真·无头”。但是相对的,除了“无头”这个很重要的点外,在系统功能上, phantomjs 比 CEFPython 还是要差不少的,最基本的,向 Web Context 的 js 全局空间注入我们自己的实现,这在 CEFPython 中是一个最直接的功能,但在 phantomjs 中我没找到。

对比 CEFPython ,有助于对 phantomjs 结构上的一个理解 —— 外部的程序运行上下文 , 跟页面的 Web Context 是互相隔离的。在 phantomjs 上只是这两部分刚好都是 js 语言的而已(而在 CEFPython 中,它们一个是 Python 一个是 js)。另一方面, phantomjs 中,这两部分的代码一般还是直接写在一起的,因为都是 js 嘛。而 CEFPython 中虽然可以,但我想没人会愿意在 Python 代码中去写 js 代码的字符串。

4. 使用

对 phantomjs 的使用,主要集中在 page 相关的 API 上,http://phantomjs.org/api/webpage/ ,而其中最关键的方法,我觉得是 evaluate /onCallback / window.callPhantom 。

phantomjs 的 page ,除了按正常浏览器流程打开页面之外,还能手动设置内容,相关的方法在setContent / injectJs ,除此而外,sendEvent 可以在浏览器的 DOM 之外模拟事件(底层一些)。

看一个典型的例子:

var fs = require('fs');
var page = require('webpage').create();

page.onError = function(msg) {
    console.log('ERROR:', msg)
};
page.onConsoleMessage = function(msg) {
    console.log('Web:', msg);
};

page.onCallback = function(data) {
    var s = data.map(function(o){ return o.text + ' | ' + o.href });
    var file = fs.open('/tmp/phantom', 'w');
    file.write(s.join('\n'));
    file.close();
    phantom.exit();
};

page.open("http://www.douban.com/group/explore", function(status) {
    if ( status === "success" ) {

        page.evaluate(function() {

            $(function () {
                var link_list = $.map(
                    $('div.channel-group-rec > .bd > ul > li > .info > .title > a'),
                    function(o) {
                        return {text: $(o).text(), href: $(o).attr('href')}
                    }
                );
                window.callPhantom(link_list);
            });


        });

    }
});

上面的代码会打开豆瓣小组页,并把“值得加入的小组”信息抽取出来,然后,会写到文件/tmp/phantomjs 中。

我知道要做这件事并不是非 phantomjs 不可,这里只是为了演示直接使用 jQuery 从页面内部解析出来了信息,然后通过 window.callPhantom 把信息传递给外部的 phantomjs 上下文,在外部使用文件系统 API 把信息写入文件保存。


目录
相关文章
|
7月前
|
Web App开发 监控 网络协议
实用的chrome命令
实用的chrome命令
1366 4
|
JavaScript 前端开发 测试技术
PhantomJS
PhantomJS 是一个基于 WebKit 的无头浏览器,它可以在不显示浏览器界面的情况下执行网页自动化任务。PhantomJS 使用 JavaScript 作为编程语言,并提供了丰富的 API 来操作网页。它支持多种操作系统,如 Windows、macOS 和 Linux 等。
181 2
|
前端开发 JavaScript Python
Python之Phantomjs无界面浏览器
Python之Phantomjs无界面浏览器
Python之Phantomjs无界面浏览器
selenium+PhantomJS
selenium+PhantomJS
94 0
|
Web App开发 数据采集 Python
Python爬虫:selenium使用chrome和PhantomJS实用参数
Python爬虫:selenium使用chrome和PhantomJS实用参数
276 0
|
Linux
Linux环境下安装phantomjs
Linux环境下安装phantomjs
428 0
|
Web App开发 数据采集 Dubbo
CentOS 6.x 搭建:Headless Chrome + ChromeDriver + Selenium基于浏览器的爬虫环境
Headless Chrome 是 Chrome 浏览器的无界面形态,可以在不打开浏览器的前提下,使用所有 Chrome 支持的特性运行你的程序。相比于现代浏览器,Headless Chrome 更加方便测试 web 应用,获得网站的截图,做爬虫抓取信息等。相比于出道较早的 PhantomJS,SlimerJS 等,Headless Chrome 则更加贴近浏览器环境。
1657 0