在某些情況下逸邦,我們需要爬取一些網(wǎng)頁(yè)恩沛,python有許多強(qiáng)大的功能庫(kù)提供我們選擇使用。對(duì)于一些動(dòng)態(tài)網(wǎng)頁(yè)缕减,也就是一些js渲染的網(wǎng)頁(yè)時(shí)雷客,我們通常會(huì)選擇使用selenium去模擬常人的瀏覽器行為。瀏覽器很多桥狡,selenium對(duì)于一些瀏覽器有不同的瀏覽器驅(qū)動(dòng)搅裙,其中一個(gè)比較常用的工具,那就是Phantomjs
什么是Phantomjs呢?
Phantomjs就是是一個(gè)無(wú)界面的,可腳本編程的WebKit瀏覽器引擎总放。它原生支持多種web 標(biāo)準(zhǔn):DOM 操作,CSS選擇器好爬,JSON局雄,Canvas 以及SVG。
內(nèi)置對(duì)象:
????????var system=require('system'); //獲得系統(tǒng)操作對(duì)象存炮,包括命令行參數(shù)炬搭、phantomjs系統(tǒng)設(shè)置等信息
? ? ? ? var page = require('webpage'); //獲取操作dom或web網(wǎng)頁(yè)的對(duì)象,通過(guò)它可以打開(kāi)網(wǎng)頁(yè)穆桂、接收網(wǎng)頁(yè)內(nèi)容宫盔、request、response參數(shù)享完,其為最核心對(duì)象灼芭。
????????var fs = require('fs'); //獲取文件系統(tǒng)對(duì)象,通過(guò)它可以操作操作系統(tǒng)的文件操作般又,包括read彼绷、write、move茴迁、copy寄悯、delete等。
一:下載安裝
http://phantomjs.org/download.htm
? ? ? ? 驗(yàn)證:輸入phantomjs -v 查看版本號(hào)堕义,得到相應(yīng)的版本號(hào)猜旬,安裝成功
二:簡(jiǎn)單程序
????????所有的學(xué)習(xí)都應(yīng)該動(dòng)手嘗試,通過(guò)例子入門phantomjs相關(guān)方法
(1)helloworld
新建一個(gè) js 文件。命名為 helloworld.js
console.log('Hello, world!');
phantom.exit();
命令行輸入:phantomjs helloworld.js
程序輸出了 Hello洒擦,world椿争!程序第二句話終止了 phantom 的執(zhí)行。
注意:phantom.exit();這句話非常重要秘遏,否則程序?qū)⒂肋h(yuǎn)不會(huì)終止
(2)頁(yè)面截圖
利用phantomjs打開(kāi)網(wǎng)頁(yè)丘薛,并將網(wǎng)頁(yè)保存為圖片
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();
});
執(zhí)行函數(shù):phantomjs pageload.js,發(fā)現(xiàn)執(zhí)行成功邦危,然后目錄下多了一張圖片洋侨,example.png
首先創(chuàng)建了一個(gè)webpage對(duì)象,然后加載本站點(diǎn)主頁(yè)倦蚪,判斷響應(yīng)狀態(tài)希坚,如果成功,那么保存截圖為 example.png陵且。render 方法裁僧,phantom 經(jīng)常會(huì)用到的網(wǎng)頁(yè)截圖功能
(3)獲得系統(tǒng)操作對(duì)象,測(cè)試某個(gè)網(wǎng)址響應(yīng)速度
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();
});
程序判斷了參數(shù)的多少慕购,如果參數(shù)不夠聊疲,那么終止運(yùn)行。然后記錄了打開(kāi)頁(yè)面的時(shí)間沪悲,請(qǐng)求頁(yè)面之后获洲,再紀(jì)錄當(dāng)前時(shí)間,二者之差就是頁(yè)面加載速度殿如。
執(zhí)行函數(shù):phantomjs loadspeed.js http://baidu.com
可能會(huì)存在亂碼現(xiàn)象
t = Date.now();
address = system.args[1];
?phantom.outputEncoding="gbk";? 添加這行代碼解決亂碼問(wèn)題
(4)獲取網(wǎng)頁(yè)源代碼
通過(guò)在網(wǎng)頁(yè)上下文中對(duì)JavaScript代碼進(jìn)行計(jì)算贡珊,使用evaluate()方法。代碼是在“沙箱(sandboxed)”中運(yùn)行的涉馁,它沒(méi)有辦法讀取在其所屬頁(yè)面上下文之外的任何JavaScript對(duì)象和變量门岔。evaluate()會(huì)返回一個(gè)對(duì)象,然而它僅限制于簡(jiǎn)單的對(duì)象并且不能包含方法或閉包烤送。通俗的說(shuō)就是獲取頁(yè)面的的源碼寒随,不能獲取console輸出的等通過(guò)js獲得的內(nèi)容
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();
});
執(zhí)行代碼輸出:
Page title is 百度一下,你就知道
任何來(lái)自于網(wǎng)頁(yè)并且包括來(lái)自 evaluate() 內(nèi)部代碼的控制臺(tái)信息帮坚,默認(rèn)不會(huì)顯示牢裳。
需要重寫這個(gè)行為,使用 onConsoleMessage 回調(diào)函數(shù)叶沛,示例可以改寫成
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();
});
這樣的話蒲讯,如果你用瀏覽器打開(kāi)百度首頁(yè),打開(kāi)調(diào)試工具的console灰署,可以看到控制臺(tái)輸出信息判帮。
重寫了 onConsoleMessage 方法之后局嘁,可以發(fā)現(xiàn)控制臺(tái)輸出的結(jié)果和我們需要輸出的標(biāo)題都打印出來(lái)了。
(5)屏幕獲取
var page = require('webpage').create();
page.open('http://github.com/', function() {
??page.render('github.png');
??phantom.exit();
});
除了png格式晦墙,還支持jpg悦昵,gif,pdf等格式晌畅。
其中最重要的方法便是 viewportSize 和 clipRect 屬性但指。
viewportSize 是視區(qū)的大小,你可以理解為你打開(kāi)了一個(gè)瀏覽器抗楔,然后把瀏覽器窗口拖到了多大棋凳。
clipRect 是裁切矩形的大小,需要四個(gè)參數(shù)连躏,前兩個(gè)是基準(zhǔn)點(diǎn)剩岳,后兩個(gè)參數(shù)是寬高。
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();
});
就相當(dāng)于把瀏覽器窗口拖到了 1024×768 大小入热,然后從左上角裁切出了 1024×768 的頁(yè)面拍棕。
(6)dom操作
腳本都是像在瀏覽器中運(yùn)行的,所以標(biāo)準(zhǔn)的 JavaScript 的 DOM 操作和 CSS 選擇器也是生效的勺良。
例如下面的例子就修改了 User-Agent绰播,然后還返回了頁(yè)面中某元素的內(nèi)容
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
首先打印出了默認(rèn)的 User-Agent,然后通過(guò)修改它尚困,請(qǐng)求驗(yàn)證 User-Agent 的一個(gè)站點(diǎn)蠢箩,通過(guò)選擇器得到了修改后的 User-Agent。
(7)使用附加庫(kù)
在1.6版本之后允許添加外部的JS庫(kù)尾组,比如下面的例子添加了jQuery忙芒,然后執(zhí)行了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()
??});
});
引用了 jQuery 之后讳侨,我們便可以在下面寫一些 jQuery 代碼了。
轉(zhuǎn)載自:靜覓???Python爬蟲(chóng)利器四之PhantomJS的用法