javascript
使用PhantomJS实现网页截图服务
使用PhantomJS實現網頁截圖服務
2015-12-12來源:Java教程人氣:99
? ? 這是上半年遇到的一個小需求,想實現網頁的抓取,并保存為圖片。研究了不少工具,效果都不理想,不是顯示太差了(Canvas、Html2Image、Cobra),就是性能不怎么樣(如SWT的Brower)。后發現無界面瀏覽器可以滿足這個條件,大致研究了一下PhantomJS與CutyCapt,兩者都是Webkit內核,其中PhantomJS使用上更方便一些,尤其在Windows平臺上,如果在linux下,從2.0版本后需要自己去機器上編譯了(大概要編譯3個小時,不得不說,g++就是個渣渣,同樣的項目,在vc下編譯快得,不談了,畢竟是免費開源的編譯器)。下面介紹PhantomJS結合java代碼實現的網頁截圖技術:
? ?
?一、環境準備
? ? 1、PhantomJS腳本的目錄:D:/xxx/phantomjs-2.0.0-windows/bin/phantomjs
? ? 2、截圖腳本:D:/xxx/phantomjs-2.0.0-windows/bin/rasterize.js
? ? 截圖的腳本在官網上有提供,但是我這里需要說明一下它的高寬度設計原理:
page.viewportSize = { width: 600, height: 600 };? ?這個是默認的高度,也就是600X600,我建議大家把height設置小一點,我這邊設置的是width:800,height:200。因為實際上,在不同時設置高度與亮度的情況下,如果真實的網頁的高度大于設置值時,圖片會自動擴充高寬度的,直到整個頁面顯示完(當你想截取小的圖片時,可能由于默認設置的太大,會使圖片有很大一塊空的)。如果同時設置了高寬度,下面的代碼會被執行,就會對網頁的部分進行截取了:
page.clipRect = { top: 0, left: 0, width: pageWidth, height: pageHeight };? ? 3、先用命令行測試一下:? ??
D:/xxx/phantomjs-2.0.0-windows/bin/phantomjs D:/xxx/phantomjs-2.0.0-windows/bin/rasterize.js http://www.QQ.com D:/test.png? ? 如果配置好了,應該可以看到生成的圖片了。當然還可以配置高寬度的參數,在上面的命令后加上:" 1000px"或" 1000px*400px",都是可以的。
?
二、服務器代碼
? ? 作為一個網頁截圖服務,這部分代碼片段應當被布署在服務器上,當然不必全照搬啦,根據自己的需求來用就好了:
1 package lekkoli.test;2 3 import java.io.BufferedInputStream;4 import java.io.BufferedReader;5 import java.io.ByteArrayOutputStream;6 import java.io.File;7 import java.io.FileInputStream;8 import java.io.IOException;9 import org.apache.log4j.Logger; 10 11 /**12 * 網頁轉圖片處理類,使用外部CMD13 * @author lekkoli14 */15 public class PhantomTools {16 17 PRivate static final Logger _logger = Logger.getLogger(PhantomTools.class);18 19 // private static final String _tempPath = "/data/temp/phantom_";20 // private static final String _shellCommand = "/usr/local/xxx/phantomjs /usr/local/xxx/rasterize.js "; Linux下的命令21 private static final String _tempPath = "D:/data/temp/phantom_";22 private static final String _shellCommand = "D:/xxx/phantomjs-2.0.0-windows/bin/phantomjs D:/xxx/phantomjs-2.0.0-windows/bin/rasterize.js "; 23 24 private String _file;25 private String _size;26 27 /**28 * 構造截圖類29 * @parm hash 用于臨時文件的目錄唯一化30 */31 public PhantomTools(int hash) {32 _file = _tempPath + hash + ".png";33 }34 35 /**36 * 構造截圖類37 * @parm hash 用于臨時文件的目錄唯一化38 * @param size 圖片的大小,如800px*600px(此時高度會裁切),或800px(此時 高度最少=寬度*9/16,高度不裁切)39 */40 public PhantomTools(int hash, String size) {41 this(hash);42 if (size != null)43 _size = " " + size;44 }45 46 /**47 * 將目標網頁轉為圖片字節流48 * @param url 目標網頁地址49 * @return 字節流50 */51 public byte[] getByteImg(String url) throws IOException {52 BufferedInputStream in = null;53 ByteArrayOutputStream out = null;54 File file = null;55 byte[] ret = null;56 try {57 if (exeCmd(_shellCommand + url + " " + _file + (_size != null ? _size : ""))) {58 file = new File(_file);59 if (file.exists()) {60 out = new ByteArrayOutputStream();61 byte[] b = new byte[5120];62 in = new BufferedInputStream(new FileInputStream(file));63 int n;64 while ((n = in.read(b, 0, 5120)) != -1) {65 out.write(b, 0, n);66 }67 file.delete();68 ret = out.toByteArray();69 }70 } else {71 ret = new byte[] {};72 }73 } finally {74 try {75 if (out != null) {76 out.close();77 }78 } catch (IOException e) {79 _logger.error(e);80 }81 try {82 if (in != null) {83 in.close();84 }85 } catch (IOException e) {86 _logger.error(e);87 }88 if (file != null && file.exists()) {89 file.delete();90 }91 }92 return ret;93 }94 95 /**96 * 執行CMD命令97 */98 private static boolean exeCmd(String commandStr) {99 BufferedReader br = null; 100 try { 101 Process p = Runtime.getRuntime().exec(commandStr); 102 if (p.waitFor() != 0 && p.exitValue() == 1) { 103 return false; 104 } 105 } catch (Exception e) { 106 _logger.error(e); 107 } finally { 108 if (br != null) { 109 try { 110 br.close(); 111 } catch (Exception e) { 112 _logger.error(e); 113 } 114 } 115 } 116 return true; 117 } 118 }? ? 使用上面的PhantomTools類,可以很方便地調用getByteImg方法來生成并獲取圖片內容?! ?/p>
? ? ?
? ? 附上我的截圖配置腳本:rasterize.js,至于PhantomJS,大家就自行去官網下載吧。
? ? 轉載請注明原址:http://www.cnblogs.com/lekko/p/4796062.html?
?
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的使用PhantomJS实现网页截图服务的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: usb device selection
- 下一篇: Hibernate 二级缓存