金沙澳门官网Python爬虫利器四之PhantomJS的用法

作者: 航空航天  发布:2019-10-01

PhantomJS是一个无界面的,可脚本编程的WebKit浏览器引擎。它原生支持多种web 标准:DOM 操作,CSS选择器,JSON,Canvas 以及SVG,同时也提供了处理文件I/O的操作,从而使你可以向操作系统读写文件等。PhantomJS的用处可谓非常广泛,诸如网络监测、网页截屏、无需浏览器的 Web 测试、页面访问自动化等。

前言

1.安装

phantomjs是完全开源的软件,可以直接下载源码编译后安装,也可以直接下载官网上编译好的文件安装。

各平台下的安装文件包地址:

windows

Mac os

Linux

下载安装包完毕后,直接解压即可。安装完成之后命令行输入
phantomjs -v 后如果出现版本号即为安装成功。

大家有没有发现之前我们写的爬虫都有一个共性,就是只能爬取单纯的html代码,如果页面是JS渲染的该怎么办呢?如果我们单纯去分析一个个后台的请求,手动去摸索JS渲染的到的一些结果,那简直没天理了。所以,我们需要有一些好用的工具来帮助我们像浏览器一样渲染JS处理的页面。

2.常用的内置对象

1.system:获得系统操作对象,包括命令行参数、phantomjs系统设置等信息

var system=require('system');

2.webpage:获取操作dom或web网页的对象,通过它可以打开网页、接收网页内容、request、response参数,其为最核心对象。提供了一套可以访问和操作web文档的核心方法,包括操作DOM、事件捕获、用户事件模拟等等。

var page = require('webpage');

3.fs:获取文件系统对象,通过它可以操作操作系统的文件操作,包括read、write、move、copy、delete等。

var fs = require('fs'); 

4.webserver:可以启动一个web服务。目前有10个并发请求的限制;任何其他请求都将排队等候。

var webserver = require('webserver');

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

3.常用API

1.通过page对象打开url链接,并可以回调其声明的回调函数,其回调发生的时机为该URL被彻底打开完毕,即该URL所引发的请求项被全部加载完,但ajax请求是与它的加载完成与否没有关系
page.open(url,function (status) {})
2.当page.open调用时,回首先执行该函数,在此可以预置一些参数或函数,用于后边的回调函数中
page.onLoadStarted = function() {}
3.page的所要加载的资源在加载过程中,出现了各种失败,则在此回调处理
page.onResourceError = function(resourceError) {}
4.page的所要加载的资源在发起请求时,都可以回调该函数
page.onResourceRequested = function(requestData, networkRequest) {}
5.page的所要加载的资源在加载过程中,每加载一个相关资源,都会在此先做出响应,它相当于http头部分, 其核心回调对象为response,可以在此获取本次请求的cookies、userAgent等
page.onResourceReceived = function(response) {}
6.欲在执行web网页时,打印一些输出信息到控制台,则可以在此回调显示。
page.onConsoleMessage = function (msg) {}
7.phantomjs是没有界面的,所以对alert也是无法直接弹出的,故phantomjs以该函数回调在page在执行过程中的alert事件
page.onAlert = function(msg) {}
8.当page.open中的url,它自己(不包括所引起的其它的加载资源)出现了异常,如404、no route to web site等,都会在此回调显示。
page.onError = function(msg, trace) {}
9.当page.open打开的url或是该url在打开过程中基于该URL进行了跳转,则可在此函数中回调。
page.onUrlChanged = function(targetUrl) {}
10.当page.open的目标URL被真正打开后,会在调用open的回调函数前调用该函数,在此可以进行内部的翻页等操作
page.onLoadFinished = function(status){}
11.在所加载的web page内部执行该函数,像翻页、点击、滑动等,均可在此中执行
page.evaluate(function(){})
12.将当前page的现状渲染成图片,输出到指定的文件中去。
page.render("")

PhantomJS

4.例子

1.输出内容。新建hello.js。

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

命令行输入phantomjs hello.js。程序输出了 Hello,world!程序第三句话终止phantom 的执行。

2.获取输入的参数。新建arguments.js.

"use strict";
var system = require('system');
if (system.args.length === 1) {
    console.log('Try to pass some args when invoking this script!');
} else {
    system.args.forEach(function (arg, i) {
            console.log(i + ': ' + arg);
    });
}
phantom.exit();

命令行输入phantomjs arguments.js https://www.baidu.com 20180106 jie
输出结果:

0: phantomjs/arguments.js
1: https://www.baidu.com
2: 20180106
3: jie

其中第一个值是当前js文件的路径

3.页面加载,并返回页面标题

"use strict";
phantom.outputEncoding="utf-8";
var page = require('webpage').create();
page.open("http://blog.csdn.net", function(status) {
        var title = page.evaluate(function() {
        return document.title;
    });
    console.log('Page title is ' + title);
    phantom.exit();
});

返回的结果:

Page title is CSDN首页-全球最大中文IT社区

4.创建web服务

var webserver = require('webserver');
var server = webserver.create();
var service = server.listen('127.0.0.1:9999', function(request, response) {
  response.statusCode = 200;
  response.write('<html><body>Hello!</body></html>');
  response.close();
});

5.设置代理

"use strict";
var page = require('webpage').create(),
    system = require('system'),
    host, port, address;

if (system.args.length < 4) {
    console.log('Usage: openurlwithproxy.js <proxyHost> <proxyPort> <URL>');
    phantom.exit(1);
} else {
    host = system.args[1];
    port = system.args[2];
    address = system.args[3];
    phantom.setProxy(host, port, 'manual', '', '');
    page.open(address, function (status) {
        if (status !== 'success') {
            console.log('FAIL to load the address "' +
                address + '" using proxy "' + host + ':' + port + '"');
        } else {
            console.log('Page title is ' + page.evaluate(function () {
                return document.title;
            }));
        }
        phantom.exit();
    });
}

Full web stack No browser required

PhantomJS is a headless WebKit scriptable with a JavaScript API. It hasfastandnativesupport for various web standards: DOM handling, CSS selector, JSON, Canvas, and SVG.

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

好,接下来我们就一起来了解一下这个神奇好用的库的用法吧。

安装

PhantomJS安装方法有两种,一种是下载源码之后自己来编译,另一种是直接下载编译好的二进制文件。然而自己编译需要的时间太长,而且需要挺多的磁盘空间。官方推荐直接下载二进制文件然后安装。

大家可以依照自己的开发平台选择不同的包进行下载

下载地址

当然如果你不嫌麻烦,可以选择

下载源码

然后自己编译。

目前(2016/3/21)最新发行版本是 v2.1,

安装完成之后命令行输入

phantomjs -v

如果正常显示版本号,那么证明安装成功了。如果提示错误,那么请重新安装。

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

官方文档

快速开始

第一个程序

第一个程序当然是Hello World,新建一个 js 文件。命名为 helloworld.js

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

phantom.exit();

命令行输入

phantomjs helloworld.js

程序输出了 Hello,world!程序第二句话终止了 phantom 的执行。

注意:phantom.exit();这句话非常重要,否则程序将永远不会终止。

页面加载

可以利用 phantom 来实现页面的加载,下面的例子实现了页面的加载并将页面保存为一张图片。

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

page.open('', function (status) {

console.log("Status: " + status);

if (status === "success") {

page.render('example.png');

}

phantom.exit();

});

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

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

phantomjs pageload.js

发现执行成功,然后目录下多了一张图片,example.png

金沙澳门官网 1

因为这个 render 方法,phantom 经常会用到网页截图的功能。

测试页面加载速度

下面这个例子计算了一个页面的加载速度,同时还用到了命令行传参的特性。新建文件保存为 loadspeed.js

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

system = require('system'),

t, address;

if (system.args.length === 1) {

console.log('Usage: loadspeed.js ');

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 

运行结果

Loading 

Loading time 11678 msec

这个时间包括JS渲染的时间,当然和网速也有关。

代码评估

To evaluate JavaScript code in the context of the web page, useevaluate()function. The execution is “sandboxed”, there is no way for the code to access any JavaScript objects and variables outside its own page context. An object can be returned fromevaluate(), however it is limited to simple objects and can’t contain functions or closures.

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

var url = '';

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 = '';

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

职位介绍:

百度一下,你就知道

啊,我没有在为百度打广告!

屏幕捕获

Since PhantomJS is using WebKit, a real layout and rendering engine, it can capture a web page as a screenshot. Because PhantomJS can render anything on the web page, it can be used to convert contents not only in HTML and CSS, but also SVG and Canvas.

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

下面的例子就捕获了github网页的截图。上文有类似内容,不再演示。

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

page.open('', function() {

page.render('github.png');

phantom.exit();

});

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

测试样例

本文由金沙澳门官网发布于航空航天,转载请注明出处:金沙澳门官网Python爬虫利器四之PhantomJS的用法

关键词:

上一篇:12月最新实习来啦,成都实习汇总第一弹
下一篇:没有了