您现在的位置: 365建站网 > 365学习 > Python爬虫制作之PhantomJS的入门用法

Python爬虫制作之PhantomJS的入门用法

文章来源:365jz.com     点击数:165    更新时间:2018-01-28 11:41   参与评论

Python爬虫制作之PhantomJS的入门用法

直接从浏览器中提取渲染好的HTML文档。如果ajax请求很多,有时请求参数还进行了加密,我们手动分析每一个Ajax请求,将成为一项繁重的工作,而且没有一定的JavaScript分析功底,很难做到。这个时候第二种方法的好处就体现出来了,直接提取浏览器渲染好的结果,不进行Ajax请求分析,PhantomJS就是这样的一个浏览器。

PhantomJS是一个基于WebKit的服务器端JavaScript API。它全面支持Web而无需浏览器支持,不仅运行快,原生支持各种Web标准:

DOM处理、CSS选择器、JSON、Canvas,和SVG。PhantomJS可以用于页面自动化、网络监测、网页截屏,以及无界面测试等。

PhantomJS可以看做一个没有界面的浏览器,它既有Firefox浏览器、

google浏览器的功能,又因为没有界面而更加快速,占更小的内存,在爬虫开发中非常受欢迎。

9.3.1 安装PhantomJS

PhantomJS安装方法有两种,一种是下载源码之后自行编译,另一种是直接下载编译好的二进制文件,官方推荐直接使用编译好的二进制文件。安装下载地址为:http://phantomjs.org/download.html,包括Windows、Mac OS、Linux版本,自行选择对应版本下载解压即可,建议为PhantomJS设置环境变量。在下载的安装包中,其中有一个example文件夹,里面有很多官方的例子可供学习和参考。

安装完成后在命令行中输入:phantomjs-v。如果正常显示版本号,则证明安装配置成功。图9-5为Windows下的显示结果。


图9-5 phantomJS版本

9.3.2 快速入门

配置完成PhantomJS,下面使用它输出“hello world”。新建一个JavaScript文件hello.js,代码内容为:

console.log('Hello, world!');
phantom.exit();

这时候在命令行中输入:

phantomjs hello.js

输出内容为:Hello,world!。代码中的第一句是在控制台输出“Hello,world!”,第二句是终止phantom的运行,不然程序会一直运行,不会停止。

通过上面的小例子我们已经了解了PhantomJS的基本操作,PhantomJS还有一些有趣而且强大功能。

1.页面加载

通过PhantomJS,一个网页可以被加载、分析和通过创建网页对象呈现。下面演示一个简单的页面加载的例子,并将当前页面进行截图保存。

pageload.js代码如下:

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

在命令行中运行:


phantomjs pageload.js

输出内容为:Status:success,并在当前目录下生成对网页的截图qiye.png,如图9-6所示。

图9-6 qiye.png

代码解释:首先使用webpage模块创建一个page对象,然后通过

page对象打开http://www.cnblogs.com/qiyeboy/网址,如果请求响应状态为success,则通过render方法将当前页面保存为qiye.png图片。

除了打开网页截图之外,还可以对网页的打开进行测速。下面的例子用来计算一个网页的加载速度,同时还用到了给JavaScript脚本传递参数的功能。loadspeed.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://www.cnblogs.com/qiyeboy/

输出结果为:

Loading http://www.cnblogs.com/qiyeboy/ Loading time 793 msec

代码解释:首先使用webpage模块创建一个page对象,使用system模块获取系统对象system,并声明了两个变量t和address,用来保存时间和传入参数。如果传入参数的长度等于1,说明要加载的地址没有传入,进行提示并退出phantom。为什么要等于1呢?因为

phantomjs loadspeed.js第一个参数是loadspeed.js。接着获取当前的时间,然后打开网页,获取加载完成后的时间,进行相减即可。

2.代码评估

为了评估网页中的JavaScript代码,可以利用evaluate。这个执行是“沙盒式”的,它不会去执行网页外的JavaScript代码。evaluate方法可以返回一个对象,然而返回值仅限于对象,不能包含函数(或闭包)。比如我们可以使用evaluate方法获取http://www.cnblogs.com/
qiyeboy/页面的标题,evaluate.js代码如下:

var url = 'http://www.cnblogs.com/qiyeboy/';
var page = require('webpage').create();

page.open(url, function(status) { var title = page.evaluate(function() { return document.title;
});
console.log('Page title is ' + title);
phantom.exit();
});

在命令行中输入:

phantomjs evaluate.js

输出结果为:

Page title is七夜的故事 - 博客园

任何来自于网页并且包括来自evaluate()内部代码的控制台信息,默认不会显示。要覆盖此行为,使用onConsoleMessage回调方法。将evaluate.js代码改动如下:

var url = 'http://www.cnblogs.com/qiyeboy/';
var page = require('webpage').create();
page.onConsoleMessage = function(msg) { console.log('Page title is ' + msg);

};
page.open(url, function(status) { page.evaluate(function() { console.log(document.title);
});
phantom.exit();
});

在命令行中输入:

phantomjs evaluate.js

输出结果为:

Page title is七夜的故事 - 博客园

9.3.3 屏幕捕获

上节简单讲解了如何将网页保存为一张图片,下面详细解释一下这个屏幕捕获的功能。由于PhantomJS使用的是WebKit内核,一个真正的布局和渲染引擎,它可以捕捉一个网页的屏幕截图。另外

PhantomJS可以渲染网页上的元素,所以它不仅可以用于HTML和CSS的内容转换,还可以用于SVG和画布。PhantomJS不仅可以将网页保存为png格式,还可以保存为jpg、gif和pdf格式。下面将

pageload.js代码进行改动,转成pdf格式,代码如下:


var page = require('webpage').create();
page.open('http://www.cnblogs.com/qiyeboy/', function(status) { console.log("Status: " + status);
if(status === "success") { page.render('qiye.pdf');
} phantom.exit();
});

最后生成的pdf文件,效果如图9-7所示。

图9-7 qiye.pdf

PhantomJS不仅可以将页面转化为不同的文件格式,还可以对视图进行缩放和裁剪,主要用到page对象中两个非常重要的属性:

viewportSize和clipRect。viewportSize是视区的大小,其作用可以看做是将打开的浏览器窗口进行缩放。clipRect是在这个视区中裁剪矩形的大小,需要四个参数,前两个是基准点,后两个参数是宽高。下面将pageload.js进行改动,代码如下:

var page = require('webpage').create();
page.viewportSize = { width: 1024, height: 768 };
page.clipRect = { top: 0, left: 0, width: 512, height: 256 };
page.open('http://www.cnblogs.com/qiyeboy/', function(status) { console.log("Status: " + status);
if(status === "success") { page.render('qiye.png');
} phantom.exit();
});

效果如图9-8所示,只是截取出了顶端一角。


图9-8 网页裁剪

9.3.4 网络监控

因为PhantomJS允许检验网络流量,因此它适合分析网络行为和性能,实现对网络的监听。当向远程服务器发送请求时,可以使用

onResourceRequested和onResourceReceived两个方法嗅探所有的资源请求和响应。示例netmonitor.js代码如下:

var url = 'http://www.cnblogs.com/qiyeboy/';
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);

在命令行中输入:

phantomjs netmonitor.js

请求和响应的信息会以JSON的格式进行显示,效果如图9-9所示。

图9-9 网络监控

9.3.5 页面自动化


PhantomJS可以加载和处理一个网页,非常适用于自动化处理,

PhantomJS中标准JavaScript的DOM操作和CSS选择器都是生效的。

下面使用一个小例子讲解一下DOM操作,获取MTime时光网的影评信息,HTML标记位置如图9-10所示。

图9-10 评分和票房标记

示例代码如下:

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

console.log('The default user agent is ' + page.settings.userAgent);
page.settings.userAgent = 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:49.0)
Gecko/20100101 Firefox/49.0';
page.open('http://movie.mtime.com/108737/', function(status) { if (status !== 'success') { console.log('Unable to access network');
} else { var ua = page.evaluate(function() { return document.getElementById('ratingRegion').textContent;
});
console.log(ua);
} phantom.exit();
});

输出结果如下:

The default user agent is Mozilla/5.0 (Windows NT 6.1; WOW64)
AppleWebKit/ 538.1(KHTML, like Gecko) PhantomJS/2.1.1 Safari/538.1 7.7总分:104,335人评分 4,299人想看音乐 画面 导演 故事 …票房:5.
92亿元

代码解释:首先创建page对象,接着将默认的User-Agent进行了修改,打开指定网页,当加载完成之后,执行DOM操作,获取id为

ratingRegion元素下的内容,并打印出来。

大家可以看一下默认UserAgent的内容,会发现里面包含了

PhantomJS关键字,一些网站就是通过这个关键字来识别是否正在使用PhantomJS爬取数据。

在1.6版本之后PhantomJS允许添加外部的JS库,比如下面的例子添加了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()
});
});

9.3.6 常用模块和方法

上面的例子中我们用到了phantom、webpage和system模块,在这三个模块基础上再讲一个fs模块。

1.phantom

对于phantom,主要讲解其中的五个方法,如表9-2所示。

表9-2 phantom方法


2.webpage

对于webpage,主要说一下includeJs、open两个普通方法,

onInitialized、onLoadFinished两个回调方法。

includeJs方法原型为includeJs(url,callback){void},功能是包含从指定的URL获取远程javaScript脚本,并执行回调方法。示例代码如下:

var webPage = require('webpage');
var page = webPage.create();
page.includeJs( // Include the https version, you can change this to http if you like.
'https:// ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js', function() { (page.evaluate(function() { // jQuery is loaded, now manipulate the DOM var $loginForm = $('form# login');

$loginForm.find('input[name="username"]').value('phantomjs');
$loginForm.find('input[name="password"]').value('c45p3r');
}))
} );

open方法比较复杂,有四种函数重载方式,分别为open(url,

callback){void}、open(url,method,callback){void}、

open(url,method,data,callback){void}、open(url,settings,

callback){void}。open(url,callback)方法之前已经用过,第二种和第三种方式类似,所以下面主要说一下后两种形式。

open(url,method,data,callback)中url为链接,method为

GET或者POST请求,data为附加的数据,callback为回调函数。示例如下,用于发送一个POST请求。

var webPage = require('webpage');
var page = webPage.create();
var postBody = 'user=username&password=password';
page.open('http://www.google.com/', 'POST', postBody, function(status) { console.log('Status: ' + status);
// Do other things here...
});

open(url,settings,callback)中url为链接,setting为对请求头

和内容的设置,callback为回调函数。示例如下:

var webPage = require('webpage');
var page = webPage.create();
var settings = { operation: "POST", encoding: "utf8", headers: { "Content-Type": "application/json"
}, data: JSON.stringify({ some: "data", another: ["custom", "data"] })
};
page.open('http://your.custom.api', settings, function(status) { console.log('Status: ' + status);
// Do other things here...
});

onInitialized是回调方法,在webpage对象被创建之后,url被加载之前被调用,主要是用来操作一些全局变量。示例代码如下:

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

page.onInitialized = function() { page.evaluate(function() { document.addEventListener('DOMContentLoaded', function() { console.log('DOM content has loaded.');
}, false);
});
};

onLoadFinished是回调方法,在页面加载完成之后调用,方法还有一个参数status。如果加载成功status为success,否则为fail。

webpage中open方法就是用这个方法作为回调函数。示例代码如下:

var webPage = require('webpage');
var page = webPage.create();
page.onLoadFinished = function(status) { console.log('Status: ' + status);
// Do other things here...
};

3.system

system模块只有属性,没有方法。下面通过表9-3列举一下

system的属性及其含义。

表9-3 system属性



4.fs

fs模块全称为File System,主要是对文件系统进行操作。该模块方法很多,这里主要讲解创建文件、判断文件是否存在、读写文件的方法,如表9-4所示。

表9-4 fs方法


以上介绍了一些常用模块和方法,如果大家想详细了解相关内容,可以去phantom官网(http://phantomjs.org/api/)查看完整的API文档。

如对本文有疑问,请提交到交流论坛,广大热心网友会为你解答!! 点击进入论坛


发表评论 (165人查看0条评论)
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
用户名: 验证码: 点击我更换图片
最新评论
------分隔线----------------------------