1. 程式人生 > >騰訊雲上PhantomJS用法示例

騰訊雲上PhantomJS用法示例

大家有沒有發現之前我們寫的爬蟲都有一個共性,就是隻能爬取單純的html程式碼,如果頁面是JS渲染的該怎麼辦呢?如果我們單純去分析一個個後臺的請求,手動去摸索JS渲染的到的一些結果,那簡直沒天理了。所以,我們需要有一些好用的工具來幫助我們像瀏覽器一樣渲染JS處理的頁面。

其中有一個比較常用的工具,那就是

PhantomJS

Full web stack No browser required
PhantomJS is a headless WebKit scriptable with a JavaScript API. It has fast andnative support for various web standards: DOM handling, CSS selector, JSON, Canvas, and SVG.
PhantomJS是一個無介面的,可指令碼程式設計的WebKit瀏覽器引擎。它原生支援多種web 標準:DOM 操作,CSS選擇器,JSON,Canvas 以及SVG。

好,接下來我們就一起來了解一下這個神奇好用的庫的用法吧。

ps:伺服器是騰訊雲

安裝

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('http://cuiqingcai.com', 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

因為這個 render 方法,phantom 經常會用到網頁截圖的功能。

測試頁面載入速度

下面這個例子計算了一個頁面的載入速度,同時還用到了命令列傳參的特性。新建檔案儲存為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://cuiqingcai.com

執行結果

Loading http://cuiqingcai.com
Loading time 11678 msec

這個時間包括JS渲染的時間,當然和網速也有關。

程式碼評估

To evaluate JavaScript code in the context of the web page, use evaluate() 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 from evaluate(), however it is limited to simple objects and can’t contain functions or closures.

利用 evaluate 方法我們可以獲取網頁的原始碼。這個執行是“沙盒式”的,它不會去執行網頁外的 JavaScript 程式碼。evalute 方法可以返回一個物件,然而返回值僅限於物件,不能包含函式(或閉包)

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();
});

以上程式碼獲取了百度的網站標題。

Page title is 百度一下,你就知道

任何來自於網頁並且包括來自evaluate()內部程式碼的控制檯資訊,預設不會顯示。

需要重寫這個行為,使用 onConsoleMessage 回撥函式,示例可以改寫成

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();
});

這樣的話,如果你用瀏覽器開啟百度首頁,開啟除錯工具的console,可以看到控制檯輸出資訊。

重寫了 onConsoleMessage 方法之後,可以發現控制檯輸出的結果和我們需要輸出的標題都打印出來了。

一張網頁,要經歷怎樣的過程,才能抵達使用者面前?
一位新人,要經歷怎樣的成長,才能站在技術之巔?
探尋這裡的祕密;
體驗這裡的挑戰;
成為這裡的主人;
加入百度,加入網頁搜尋,你,可以影響世界。

請將簡歷傳送至 %c [email protected]( 郵件標題請以“姓名-應聘XX職位-來自console”命名) color:red
職位介紹:http://dwz.cn/hr2013
百度一下,你就知道

啊,我沒有在為百度打廣告!

螢幕捕獲

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('http://github.com/', function() {
  page.render('github.png');
  phantom.exit();
});

除了 png 格式的轉換,PhantomJS還支援 jpg,gif,pdf等格式。

測試樣例

其中最重要的方法便是 viewportSize 和 clipRect 屬性。

viewportSize 是視區的大小,你可以理解為你打開了一個瀏覽器,然後把瀏覽器視窗拖到了多大。

clipRect 是裁切矩形的大小,需要四個引數,前兩個是基準點,後兩個引數是寬高。

通過下面的小例子感受一下。

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();
});

執行結果

就相當於把瀏覽器視窗拖到了 1024×768 大小,然後從左上角裁切出了 1024×768 的頁面。

網路監聽

Because PhantomJS permits the inspection of network traffic, it is suitable to build various analysis on the network behavior and performance.

因為 PhantomJS 有網路通訊的檢查功能,它也很適合用來做網路行為的分析。

When a page requests a resource from a remote server, both the request and the response can be tracked via onResourceRequested and onResourceReceived callback.

當接受到請求時,可以通過改寫onResourceRequested和onResourceReceived回撥函式來實現接收到資源請求和資源接受完畢的監聽。例如

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

執行結果會打印出所有資源的請求和接收狀態,以JSON格式輸出。

頁面自動化處理

Because PhantomJS can load and manipulate a web page, it is perfect to carry out various page automations.

因為 PhantomJS 可以載入和操作一個web頁面,所以用來自動化處理也是非常適合的。

DOM操作

Since the script is executed as if it is running on a web browser, standard DOM scripting and CSS selectors work just fine.

指令碼都是像在瀏覽器中執行的,所以標準的 JavaScript 的 DOM 操作和 CSS 選擇器也是生效的。

例如下面的例子就修改了 User-Agent,然後還返回了頁面中某元素的內容。

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

首先打印出了預設的 User-Agent,然後通過修改它,請求驗證 User-Agent 的一個站點,通過選擇器得到了修改後的 User-Agent。

使用附加庫

在1.6版本之後允許新增外部的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()
  });
});

引用了 jQuery 之後,我們便可以在下面寫一些 jQuery 程式碼了。

Webpage物件

在前面我們介紹了 webpage 物件的幾個方法和屬性,其實它本身還有其它很多的屬性。具體的內容可以參考

裡面介紹了 webpage的所有屬性,方法,回撥。

命令列

Command-line Options

PhantomJS提供的命令列選項有:

  • –help or -h lists all possible command-line options. Halts immediately, will not run a script passed as argument. [幫助列表]

  • –version or -v prints out the version of PhantomJS. Halts immediately, will not run a script passed as argument. [檢視版本]

  • –cookies-file=/path/to/cookies.txt specifies the file name to store the persistent Cookies. [指定存放cookies的路徑]

  • –disk-cache=[true|false] enables disk cache (at desktop services cache storage location, default is false). Also accepted: [yes|no]. [硬碟快取開關,預設為關]

  • –ignore-ssl-errors=[true|false] ignores SSL errors, such as expired or self-signed certificate errors (default is false). Also accepted: [yes|no]. [忽略ssl錯誤,預設不忽略]

  • –load-images=[true|false] load all inlined images (default is true). Also accepted: [yes|no]. [載入圖片,預設為載入]

  • –local-storage-path=/some/path path to save LocalStorage content and WebSQL content. [本地儲存路徑,如本地檔案和SQL檔案等]

  • –local-storage-quota=number maximum size to allow for data. [本地檔案最大大小]

  • –local-to-remote-url-access=[true|false] allows local content to access remote URL (default is false). Also accepted: [yes|no]. [是否允許遠端載入檔案,預設不允許]

  • –max-disk-cache-size=size limits the size of disk cache (in KB). [最大快取空間]

  • –output-encoding=encoding sets the encoding used for terminal output (default is utf8). [預設輸出編碼,預設utf8]

  • –remote-debugger-port starts the script in a debug harness and listens on the specified port [遠端除錯埠]

  • –remote-debugger-autorun runs the script in the debugger immediately: ‘yes’ or ‘no’ (default) [在除錯環境下是否立即執行指令碼,預設否]

  • –proxy=address:port specifies the proxy server to use (e.g. –proxy=192.168.1.42:8080). [代理]

  • –proxy-type=[http|socks5|none] specifies the type of the proxy server (default is http). [代理型別,預設http]

  • –proxy-auth specifies the authentication information for the proxy, e.g. –proxy-auth=username:password). [代理認證]

  • –script-encoding=encoding sets the encoding used for the starting script (default is utf8). [指令碼編碼,預設utf8]

  • –ssl-protocol=[sslv3|sslv2|tlsv1|any’] sets the SSL protocol for secure connections (default is SSLv3). [SSL協議,預設SSLv3]

  • –ssl-certificates-path= Sets the location for custom CA certificates (if none set, uses system default). [SSL證書路徑,預設系統預設路徑]

  • –web-security=[true|false] enables web security and forbids cross-domain XHR (default is true). Also accepted: [yes|no]. [是否開啟安全保護和禁止異站Ajax,預設開啟保護]

  • –webdriver starts in ‘Remote WebDriver mode’ (embedded GhostDriver): ‘[[:]]’ (default ‘127.0.0.1:8910’) [以遠端WebDriver模式啟動]

  • –webdriver-selenium-grid-hub URL to the Selenium Grid HUB: ‘URLTOHUB’ (default ‘none’) (NOTE: works only together with ‘–webdriver’) [Selenium介面]

  • –config=/path/to/config.json can utilize a JavaScript Object Notation (JSON) configuration file instead of passing in multiple command-line optionss [所有的命令列配置從config.json中讀取]

注:JSON檔案配置格式

{
  /* Same as: --ignore-ssl-errors=true */
  "ignoreSslErrors": true,

  /* Same as: --max-disk-cache-size=1000 */
  "maxDiskCacheSize": 1000,

  /* Same as: --output-encoding=utf8 */
  "outputEncoding": "utf8"

  /* etc. */
}

There are some keys that do not translate directly:

 * --disk-cache => diskCacheEnabled
 * --load-images => autoLoadImages
 * --local-storage-path => offlineStoragePath
 * --local-storage-quota => offlineStorageDefaultQuota
 * --local-to-remote-url-access => localToRemoteUrlAccessEnabled
 * --web-security => webSecurityEnabled

以上是命令列的基本配置

例項

在此提供官方文件例項,多對照例項練習,使用起來會更得心應手。

官方例項

結語

以上是博主對 PhantomJS 官方文件的基本總結和翻譯,如有差錯,希望大家可以指正。另外可能有的小夥伴覺得這個工具和 Python 有什麼關係?不要急,後面會有 Python 和 PhantomJS 的綜合使用的。

相關推薦

PhantomJS用法示例

大家有沒有發現之前我們寫的爬蟲都有一個共性,就是隻能爬取單純的html程式碼,如果頁面是JS渲染的該怎麼辦呢?如果我們單純去分析一個個後臺的請求,手動去摸索JS渲染的到的一些結果,那簡直沒天理了。所以,我們需要有一些好用的工具來幫助我們像瀏覽器一樣渲染JS處理的頁面。

從教務網爬蟲程序到的運行

pytho 創建 輸入 ubunt 雲服務 test CP user ann 從教務網爬蟲程序到騰訊雲上的運行 主要內容有以下幾方面: pip3以及相關python包的安裝 mysql數據庫的連接以及相關操作 騰訊雲服務器的設置與連接,文件傳輸等操作 pip3以及相關p

如何在安裝Cloud Foundry

Cloud Foundry是VMware推出的業界第一個開源PaaS雲平臺,它支援多種框架、語言、執行時環境、雲平臺及應用服務,使開發人員能夠在幾秒鐘內進行應用程式的部署和擴充套件,無需擔心任何基礎架構的問題。 雲伺服器(Cloud Virtual Machin

安裝MySQL

首先安裝MySQL: sudo apt-get install mysql-server sudo apt-get install mysql-client sudo apt-get install libmysqlclient-dev 安裝時記得設定密碼!!! 安

1小時教你把javaweb部署到詳細教程(centOS6.6版本,jdk1.7+tomcat8+mysql)

最近想要把自己寫的web專案部署到騰訊雲上進行訪問,但是騰訊雲也不出一個官方的配置教程,像我們這種剛入門的新手完全懵逼。在百度上面搜了很久都沒有詳細的教程,都是在過程中出現各種各樣的問題,所以現在我就把我自己對騰訊雲的配置過程一步步的寫下來,希望大家能夠少走一些彎路。 其實

搭建Ubuntu伺服器

首先在騰訊雲上重灌系統並且設定好密碼登入安裝apache2sudo apt-get install apache2安裝phpsudo apt-get install php連線apache2與phpsu

spring-boot gradle vue 前後端分離專案在部署到 tomcat nginx

前言 因為種種原因,把後端部署在 tomcat 上,前端專案部署在 nginx 上。 Tomcat tomcat 的執行沒什麼說的,將專案打包為 war,放在 webapps 下,啟動 tomcat 會自動解壓 war 包。 spring-boot

如何用Baas快速在開發小程式-系列3 :實現COS API呼叫

一、實驗簡介 本實驗通過呼叫騰訊雲物件儲存(COS)介面,實現將圖片上傳到指定的 Bucket 功能;同時封裝圖片上傳介面,用於上傳商品圖片。 二、實驗目標 掌握 RESTFul API 介面呼叫和除錯方法掌握 RESTFul API 封裝方法 三、實驗步驟

從零開始搭建的 SpringBoot 容器化應用

歡迎大家前往雲+社群,獲取更多騰訊海量技術實踐乾貨哦~ 作者:李想 由於最近容器技術的火熱,各大雲端計算廠商都已經提供了獨立的容器服務,騰訊雲也不例外。騰訊雲容器服務的官方文件提供了一個基於Node.js的簡單案例供大家上手,考慮到官方的文件並沒有提供基於Java的

Redis在配置遠端訪問-bind

Redis遠端訪問 若遠端主機需要訪問redis伺服器,可以修改redis.conf配置檔案 bind欄位預設為: bind 127.0.0.1 這樣只能本機訪問redis 若允許遠端主機訪問,可註釋掉bind行 或者 將bind 127.0.0

Django+vue在搭建前後端分離項目

.gz attr 名稱 info 路由 run 天前 配置 靜態    最近打算用Django+vue搭建一個個人主站,在此記錄一下搭建項目的整個過程。 一 開發環境:   騰訊雲Centos 7   Python 3.7  

小程序用thinkPHP傳文件到對象存儲空間

php<?php/** * Created by PhpStorm. * User: Administrator * Date: 2017/11/22 * Time: 10:48 */ namespace Home\Controller;//命名空間 require(‘cos-php-sd

視頻 點播 視頻傳接口

none demo under fun time body ces nat pat 申請騰訊雲 獲取id 及 key 【騰訊雲視頻】Web上傳 地址 https://cloud.tencent.com/document/product/266/9239

CentOS 7 安裝Nginx

lease 安裝nginx sta add ref roo AD 傳輸 als 以下安裝步驟需要root權限。 添加CentOS 7 EPEL 倉庫 sudo yum install epel-release 安裝Nginx sudo yum install nginx

微信小程序基於對象存儲的圖片

don format isp manager reg false serial key .net 在使用騰訊雲對象存儲之前,公司一直使用的是傳統的FTP的上傳模式,而隨著用戶量的不斷增加,FTP所暴露出來的問題也越來越多,1.傳輸效率低,上傳速度慢。2.時常

pureftpd在的VPS安裝配置

pureftpd在騰訊雲的VPS上安裝配一、環境介紹: vps系統是CentOS Linux release 7.3.1611 (Core) 第一塊網卡是內網卡 二、pureftpd采用源碼編譯安裝: 下載安裝包以及編譯安裝過程 yum -y install make gcc gcc-c++ gcc-g77

微信小程序/網站 傳圖片到COS

arr n) ram index.php 函數返回 tps etag 循環 5.0 COS簡介: 騰訊雲提供的一種對象存儲服務,供開發者存儲海量文件的分布式存儲服務。可以將自己開發的應用的存儲部分全部接入COS的存儲桶中,有效減少應用服務器的帶寬,請求等。個人也可以通過騰訊

Python實現CDB備份文件自動傳到COS

requests 簡單 level color eid zip part 雲平臺 python3 一、背景 需求:目前遇到的客戶需求為將騰訊雲CDB備份文件自動上傳到騰訊雲COS內,再次拋磚引玉,還有很多類似的需求均可以采用此類方法解決,線下IDC數據文件備份至雲端COS

從0開始在服務器搭建python3+flask+uwsgi+nginx服務器

我們 mac make ssl 騰訊雲 sgi 配置文件 wsgi div 以ssh方式連接騰訊雲,以mac為例 一、安裝Python3、flask、uwsgi和nginx (一)安裝基礎包 1、因為缺少gcc,沒法make,所以安裝gcc yum -y install

ssh連線、華為Linux伺服器,一會就自動斷開

客戶端向服務端傳送心跳 依賴 ssh 客戶端定時傳送心跳,putty、SecureCRT、XShell 都有這個功能。 Linux / Unix 下,編輯 ssh 配置檔案: # vim /etc/ssh/ssh_config 新增 ServerAliveInterval 20ServerAliveC