[Python爬蟲] 在Windows下安裝PhantomJS和CasperJS及入門介紹(上)

Eastmount發表於2015-08-19
        最近在使用Python爬取網頁內容時,總是遇到JS臨時載入、動態獲取網頁資訊的困難。例如爬取CSDN下載資源評論、搜狐圖片中的“原圖”等,此時嘗試學習Phantomjs和CasperJS來解決這個問題。這第一篇文章當然就是安裝過程及入門介紹。

一. 安裝Phantomjs

        下載地址:http://phantomjs.org/
        官網介紹:
          PhantomJS is a headless WebKit scriptable with a JavaScript API. It has fast and native support for various web standards: DOM handling, CSS selector, JSON, Canvas, and SVG.
          Full web stack No browser required.
        PhantomJS是一個伺服器端的 JavaScript API 的WebKit(開源的瀏覽器引擎)。其支援各種Web標準: DOM 處理, CSS 選擇器, JSON, Canvas 和 SVG。PhantomJS可以用於頁面自動化,網路監測,網頁截圖,以及無介面測試等。

        下載PhantomJS解壓後如下圖所示:


        在該資料夾下建立test.js檔案,程式碼如下:
console.log('Hello world!');
phantom.exit();
        通過Ctrl+R開啟CMD呼叫phantomjs.exe執行該程式輸出如下圖所示:


        參考官方文件:http://phantomjs.org/documentation/
        1、指令碼引數-arguments.js
        同時其自帶的examples資料夾中有很多模板程式碼,其中獲取指令碼引數程式碼如下:

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 examples/arguments.js arg0 agr1 arg2 arg3


        2、網頁截圖
        在根目錄新建檔案loadpic.js,其程式碼如下:
var page = require('webpage').create();
page.open('http://www.baidu.com', function () {
    page.render('example.png');
    phantom.exit();
});
        執行程式結果如下圖所示:
        phantomjs loadpic.js

        短短5行程式碼讓我第一次體會到了PhantomJS和呼叫指令碼函式的強大,它載入baidu頁面並儲存為一張PNG圖片,這個特性可以廣泛適用於網頁快拍、獲取網頁線上知識等功能。同時也感受到了似乎能夠解決我最初的載入JS問題。

        3、頁面載入-Page Loading
          A web page can be loaded, analyzed, and rendered by creating a web page object.
        通過建立一個網頁物件,一個網頁可以被載入,分析和渲染。examples資料夾中的loadspeed.js指令碼載入一個特殊的URL (不要忘了http協議) 並且計量載入該頁面的時間。
var page = require('webpage').create(),
    system = require('system'),
    t, address;

if (system.args.length === 1) {
    console.log('Usage: loadspeed.js <some URL>');
    phantom.exit(1);
} else {
    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('Page title is ' + page.evaluate(function () {
                return document.title;
            }));
            console.log('Loading time ' + t + ' msec');
        }
        phantom.exit();
    });
}
        執行程式如所示:
        phantomjs examples/loadspeed.js http://www.baidu.com
        其中包括document.title獲取網頁標題和t=Date.now()-t計算網頁載入時間。此時輸出如下圖所示,但會存在中文亂碼,如何解決呢?


        新增如下程式碼即可:
        t = Date.now();
        address = system.args[1];
        phantom.outputEncoding="gbk";



        4.程式碼運算-Code Evaluation
        通過在網頁上下文中對JavaScript程式碼進行計算,使用evaluate()方法。程式碼是在“沙箱(sandboxed)”中執行的,它沒有辦法讀取在其所屬頁面上下文之外的任何JavaScript物件和變數。evaluate()會返回一個物件,然而它僅限制於簡單的物件並且不能包含方法或閉包。
        下面這段程式碼用於顯示網頁標題:
var page = require('webpage').create();
page.open('http://www.csdn.net', function(status) {
  var title = page.evaluate(function() {
    return document.title;
  });
  phantom.outputEncoding="gbk";
  console.log('Page title is ' + title);
  phantom.exit();
});
        輸出如下圖所示:
        任何來自於網頁並且包括來自evaluate()內部程式碼的控制檯資訊,預設不會顯示的。要重寫這個行為,使用onConsoleMessage回撥函式,前一個示例可以被改寫成:
var page = require('webpage').create();
phantom.outputEncoding="gbk";
page.onConsoleMessage = function(msg) {
  console.log('Page title is ' + msg);
};
page.open('http://www.csdn.net', function(status) {
  page.evaluate(function() {
    console.log(document.title);
  });
  phantom.exit();
});
        呼叫phantomjs gettile2.js即可。

        5.DOM操作-DOM Manipulation
        因為指令碼好像是一個Web瀏覽器上執行的一樣,標準的DOM指令碼和CSS選擇器可以很好的工作。這使得PhantomJS適合支援各種頁面自動化任務。
        參考page automation tasks
        下面的 useragent.js(examples檔案樣本)將讀取id 為myagent的元素的 textContent 屬性:
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').innerText;
        });
        console.log(ua);
    }
    phantom.exit();
});
        輸入如下指令,獲取id=myagent元素的值:
        phantomjs examples/useragent.js

         上面示例也提供了一種自定義user agent的方法。
         使用JQuery及其他類庫(Use jQuery and Other Libraries)。如果版本是1.6,你也可以把jQuery放入你的頁面中,使用page.includeJs如下:
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()
  });
});
          The above snippet will open up a web page, include the jQuery library into the page, and then click on all buttons using jQuery. It will then exit from the web page. Make sure to put the exit statement within the page.includeJs or else it may exit prematurely before the javascript code is included.
        即需要確保JavaScript程式碼中包括引用的頁面存在。The Webpage instance具體用法參考前面官方文件。

        6.網路請求及響應 – Network Requests and Responses
        當一個頁面從一臺遠端伺服器請求一個資源的時候,請求和響應均可以通過 onResourceRequested 和 onResourceReceived 回撥方法追蹤到。文件示例 netlog.js:
var page = require('webpage').create(),
    system = require('system'),
    address;

if (system.args.length === 1) {
    console.log('Usage: netlog.js <some URL>');
    phantom.exit(1);
} else {
    address = system.args[1];

    page.onResourceRequested = function (req) {
        console.log('requested: ' + JSON.stringify(req, undefined, 4));
    };

    page.onResourceReceived = function (res) {
        console.log('received: ' + JSON.stringify(res, undefined, 4));
    };

    page.open(address, function (status) {
        if (status !== 'success') {
            console.log('FAIL to load the address');
        }
        phantom.exit();
    });
}
        輸入指令:
        phantomjs examples/netlog.js http://www.baidu.com
       
輸出部分內容:
received: {
    "contentType": "text/javascript; charset=gbk",
    "headers": [
        {
            "name": "Server",
            "value": "bfe/1.0.8.5"
        },
        {
            "name": "Date",
            "value": "Tue, 18 Aug 2015 20:10:03 GMT"
        },
        {
            "name": "Content-Type",
            "value": "text/javascript; charset=gbk"
        },
        {
            "name": "Content-Length",
            "value": "88"
        },
        {
            "name": "Connection",
            "value": "keep-alive"
        },
        {
            "name": "Cache-Control",
            "value": "private"
        }
    ],
    "id": 13,
    "redirectURL": null,
    "stage": "end",
    "status": 200,
    "statusText": "OK",
    "time": "2015-08-18T20:09:38.085Z",
    "url": "https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=&json=1&p=3&
sid=16486_16222_1421_16896_16738_12825_12868_16800_16659_16424_16514_15936_12073
_13932_16866&csor=0&cb=jQuery110208203572703059763_1439928574608&_=1439928574609
"
}
        獲取如何把該特性用於HAR 輸出以及基於YSlow的效能分析的更多資訊,請參閱網路監控頁面:network monitoring
        下面顯示了從英國廣播公司網站獲得典範的瀑布圖(waterfall diagram):
        
        PS:其他本分參考官方文件,目錄如下,examples中包括每個js對應的用途、github中原始碼、Troubleshooting等。

二. 安裝CasperJS

        下載地址:http://casperjs.org/
        官方文件:http://docs.casperjs.org/en/latest/
        PS:準備下一篇文章介紹

參考資料:
        用CasperJs自動瀏覽頁面-by:kiwi小白 CSDN
        PhantomJS安裝及快速入門教程
        Windows中Phantomjs + Casperjs安裝使用方法
        CasperJS 的安裝和快速入門-oschina
        使用 CasperJS 對 Web 網站進行功能測試-oschina
        利用nodejs+phantomjs+casperjs採集淘寶商品的價格
        [譯]CasperJS,基於PhantomJS的工具包

        最後希望文章對你有所幫助吧!如果有不足之處,還請海涵~
      (By:Eastmount 2015-8-19 深夜4點半   http://blog.csdn.net/eastmount/

相關文章