最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java利用phantomjs進(jìn)行截圖實(shí)例教程

 更新時(shí)間:2018年10月11日 10:46:58   作者:這個(gè)名字有點(diǎn)特別  
PlantomJs是一個(gè)基于javascript的webkit內(nèi)核無(wú)頭瀏覽器 也就是沒(méi)有顯示界面的瀏覽器,你可以在基于 webkit 瀏覽器做的事情,它都能做到。下面這篇文章主要給大家介紹了關(guān)于java利用phantomjs進(jìn)行截圖的相關(guān)資料,需要的朋友可以參考下

前言

最近工作中遇到一個(gè)需求,需要實(shí)現(xiàn)截圖功能,斷斷續(xù)續(xù)查找資料、驗(yàn)證不同的實(shí)現(xiàn)方法終于算基本搞定了頁(yè)面截圖,因?yàn)橹虚g過(guò)程曲折花費(fèi)較多時(shí)間,分享出來(lái)幫助大家快速實(shí)現(xiàn)截圖

為什么選用phantomjs進(jìn)行截圖

截圖可以實(shí)現(xiàn)的方式有很多,比如:

  • selenium
  • HtmlUnit
  • Html2Image、、、and so on但是這些實(shí)現(xiàn)的截圖效果都不好。selenium只能實(shí)現(xiàn)截屏,不能截取整個(gè)頁(yè)面,而HtmlUnit、Html2Image對(duì)js的支持效果并不好,截下來(lái)的圖會(huì)有很多空白。phantomjs就是萬(wàn)精油了,既能截取整個(gè)頁(yè)面,對(duì)js支持的效果又好

PlantomJs提供了如 CSS 選擇器、DOM操作、JSON、HTML5、Canvas、SVG 等。PhantomJS 的用處很廣泛,如網(wǎng)絡(luò)監(jiān)控、網(wǎng)頁(yè)截屏、頁(yè)面訪問(wèn)自動(dòng)化、無(wú)需瀏覽器的 Web 測(cè)試等,這里只用到網(wǎng)頁(yè)截屏。

前期準(zhǔn)備

安裝phantomjs。mac os

brew install phantomjs

命令行的方式進(jìn)行截圖

安裝以后我們就可以小試牛刀了

打開(kāi)終端,輸入以下命令:

/Users/hetiantian/SoftWares/phantomjs/bin/phantomjs
/Users/hetiantian/SoftWares/phantomjs/examples/rasterize.js
https://juejin.im/post/5bb24bafe51d450e4437fd96
/Users/hetiantian/Desktop/juejin-command.png

查看效果

發(fā)現(xiàn)圖片沒(méi)有加載好

來(lái)看以下剛剛的命令行:

/Users/hetiantian/SoftWares/phantomjs/bin/phantomjs:phantomjs可執(zhí)行文件保存地址
/Users/hetiantian/SoftWares/phantomjs/examples/rasterize.js:rasterize.js文件地址

這段命令可以理解為用phantomjs去運(yùn)行rasterize.js文件,所以要想解決圖片空白的問(wèn)題我們需要去看一下rasterize.js文件。

"use strict";
var page = require('webpage').create(),
 system = require('system'),
 address, output, size, pageWidth, pageHeight;

if (system.args.length < 3 || system.args.length > 5) {
 console.log('Usage: rasterize.js URL filename [paperwidth*paperheight|paperformat] [zoom]');
 console.log(' paper (pdf output) examples: "5in*7.5in", "10cm*20cm", "A4", "Letter"');
 console.log(' image (png/jpg output) examples: "1920px" entire page, window width 1920px');
 console.log('         "800px*600px" window, clipped to 800x600');
 phantom.exit(1);
} else {
 address = system.args[1];
 output = system.args[2];
 page.viewportSize = { width: 600, height: 600 };
 if (system.args.length > 3 && system.args[2].substr(-4) === ".pdf") {
  size = system.args[3].split('*');
  page.paperSize = size.length === 2 ? { width: size[0], height: size[1], margin: '0px' }
           : { format: system.args[3], orientation: 'portrait', margin: '1cm' };
 } else if (system.args.length > 3 && system.args[3].substr(-2) === "px") {
  size = system.args[3].split('*');
  if (size.length === 2) {
   pageWidth = parseInt(size[0], 10);
   pageHeight = parseInt(size[1], 10);
   page.viewportSize = { width: pageWidth, height: pageHeight };
   page.clipRect = { top: 0, left: 0, width: pageWidth, height: pageHeight };
  } else {
   console.log("size:", system.args[3]);
   pageWidth = parseInt(system.args[3], 10);
   pageHeight = parseInt(pageWidth * 3/4, 10); // it's as good an assumption as any
   console.log ("pageHeight:",pageHeight);
   page.viewportSize = { width: pageWidth, height: pageHeight };
  }
 }
 if (system.args.length > 4) {
  page.zoomFactor = system.args[4];
 }
 page.open(address, function (status) {
  if (status !== 'success') {
   console.log('Unable to load the address!');
   phantom.exit(1);
  } else {
   window.setTimeout(function () {
    page.render(output);
    phantom.exit();
   }, 200);
  }
 });
}

嘗試一:

對(duì)page.viewportSize = { width: 600, height: 600 };產(chǎn)生了疑問(wèn)🤔️

把height調(diào)大十倍,發(fā)現(xiàn)基本是完美截圖了,但是如果頁(yè)面的篇幅特別短,會(huì)發(fā)現(xiàn)有瑕疵,下面留有一大片空白。原因:page.viewportSize = { width: 600, height: 600 };設(shè)置的是初始打開(kāi)瀏覽器的大小,通過(guò)增大這個(gè)值可以加載js。如果我們能拿到實(shí)際頁(yè)面的大小在設(shè)置height大小,但是不,我不能。

并且不能接受預(yù)先設(shè)定一個(gè)很大的height值,比如30000,因?yàn)椴荒芙邮艿紫铝舭椎男Ч?br />

嘗試二:

在window.setTimeout方法之前加入以下代碼

 page.evaluate(function(){
  scrollBy(0, 18000); 
});

無(wú)奈evaluate里不能在用for循環(huán)了,前端渣渣真的不知道如何改,遂放棄

java代碼方式進(jìn)行截圖

需要的依賴

  <dependency>
   <groupId>org.seleniumhq.selenium</groupId>
   <artifactId>selenium-java</artifactId>
   <version>2.45.0</version>
  </dependency>

  <dependency>
   <groupId>com.codeborne</groupId>
   <artifactId>phantomjsdriver</artifactId>
   <version>1.2.1</version>
   <!-- this will _always_ be behind -->
   <exclusions>
    <exclusion>
     <groupId>org.seleniumhq.selenium</groupId>
     <artifactId>selenium-java</artifactId>
    </exclusion>
    <exclusion>
     <groupId>org.seleniumhq.selenium</groupId>
     <artifactId>selenium-remote-driver</artifactId>
    </exclusion>
   </exclusions>
  </dependency>

代碼實(shí)現(xiàn)

public class PhantomjsTest2 {
 public static void main(String[] args) throws InterruptedException, IOException {
  //設(shè)置必要參數(shù)
  DesiredCapabilities dcaps = new DesiredCapabilities();
  //ssl證書(shū)支持
  dcaps.setCapability("acceptSslCerts", true);
  //截屏支持
  dcaps.setCapability("takesScreenshot", true);
  //css搜索支持
  dcaps.setCapability("cssSelectorsEnabled", true);
  //js支持
  dcaps.setJavascriptEnabled(true);
  //驅(qū)動(dòng)支持(第二參數(shù)表明的是你的phantomjs引擎所在的路徑)
  dcaps.setCapability(PhantomJSDriverService.PHANTOMJS_EXECUTABLE_PATH_PROPERTY,
    "/Users/hetiantian/SoftWares/phantomjs/bin/phantomjs");
  //創(chuàng)建無(wú)界面瀏覽器對(duì)象
  PhantomJSDriver driver = new PhantomJSDriver(dcaps);

  //設(shè)置隱性等待(作用于全局)
  driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
  long start = System.currentTimeMillis();
  //打開(kāi)頁(yè)面
  driver.get("https://juejin.im/post/5bb24bafe51d450e4437fd96");
  Thread.sleep(30 * 1000);
  JavascriptExecutor js = driver;
  for (int i = 0; i < 33; i++) {
   js.executeScript("window.scrollBy(0,1000)");
   //睡眠10s等js加載完成
   Thread.sleep(5 * 1000);
  }
  //指定了OutputType.FILE做為參數(shù)傳遞給getScreenshotAs()方法,其含義是將截取的屏幕以文件形式返回。
  File srcFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
  Thread.sleep(3000);
  //利用FileUtils工具類的copyFile()方法保存getScreenshotAs()返回的文件對(duì)象
  FileUtils.copyFile(srcFile, new File("/Users/hetiantian/Desktop/juejin-01.png"));
  System.out.println("耗時(shí):" + (System.currentTimeMillis() - start) + " 毫秒");
 }
}

注釋已經(jīng)夠詳細(xì)了不多說(shuō)了。唯一說(shuō)一點(diǎn):通過(guò)去執(zhí)行js代碼實(shí)現(xiàn)頁(yè)面滑動(dòng),并且每次滑動(dòng)都會(huì)通過(guò)睡眠保證有時(shí)間可以將 js加載進(jìn)來(lái)。會(huì)調(diào)用33次滑動(dòng),因?yàn)閜hantomjs截取最大的高度為32767px(int  32位的最大整數(shù)),所以滑動(dòng)33次可以保證能夠截取到的最大頁(yè)面部分其js已經(jīng)是加載完成了的

附:window.scrollBy(0,1000)、window.scrollTo(0,1000)的區(qū)別

window.scrollBy(0,1000)
window.scrollBy(0,1000)
執(zhí)行到這里頁(yè)面滑動(dòng)1000+1000px
window.scrollTo(0,1000)
window.scrollTo(0,1000)
執(zhí)行到這里頁(yè)面滑動(dòng)到1000px處

window.scrollTo(0, document.body.scrollHeight可以滑動(dòng)到頁(yè)面底部,不選擇有兩個(gè)原因:

1)一下子滑動(dòng)到底部js會(huì)來(lái)不及被加載

2)有些頁(yè)面沒(méi)有底部,可以一直滑動(dòng)加載

注:這里所說(shuō)的js來(lái)不及加載指的是:想要截取頁(yè)面的js來(lái)不及加載

該方式的缺點(diǎn):比較費(fèi)時(shí)間。果然熊和魚(yú)掌不可兼得也,統(tǒng)計(jì)了一下截取一張圖片大概需要四分多鐘

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。

相關(guān)文章

  • Java超詳細(xì)梳理異常處理機(jī)制

    Java超詳細(xì)梳理異常處理機(jī)制

    異常就是不正常,比如當(dāng)我們身體出現(xiàn)了異常我們會(huì)根據(jù)身體情況選擇喝開(kāi)水、吃藥、看病、等?異常處理方法。?java異常處理機(jī)制是我們java語(yǔ)言使用異常處理機(jī)制為程序提供了錯(cuò)誤處理的能力,程序出現(xiàn)的錯(cuò)誤,程序可以安全的退出,以保證程序正常的運(yùn)行等
    2022-04-04
  • SpringBoot?集成Resteasy實(shí)現(xiàn)RESTFul接口的詳細(xì)過(guò)程

    SpringBoot?集成Resteasy實(shí)現(xiàn)RESTFul接口的詳細(xì)過(guò)程

    這篇文章主要介紹了SpringBoot集成Resteasy實(shí)現(xiàn)RESTFul接口,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-08-08
  • 解決Dubbo應(yīng)用啟動(dòng)注冊(cè)ZK獲取IP慢的原因之一

    解決Dubbo應(yīng)用啟動(dòng)注冊(cè)ZK獲取IP慢的原因之一

    這篇文章主要介紹了解決Dubbo應(yīng)用啟動(dòng)注冊(cè)ZK獲取IP慢的原因之一,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-04-04
  • springboot jpa分庫(kù)分表項(xiàng)目實(shí)現(xiàn)過(guò)程詳解

    springboot jpa分庫(kù)分表項(xiàng)目實(shí)現(xiàn)過(guò)程詳解

    這篇文章主要介紹了springboot jpa分庫(kù)分表項(xiàng)目實(shí)現(xiàn)過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-01-01
  • springboot?serviceImpl初始化注入對(duì)象實(shí)現(xiàn)方式

    springboot?serviceImpl初始化注入對(duì)象實(shí)現(xiàn)方式

    這篇文章主要介紹了springboot?serviceImpl初始化注入對(duì)象實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • springboot2.5.0和redis整合配置詳解

    springboot2.5.0和redis整合配置詳解

    本篇文章向大家介紹springboot2.5.0 整合 redis 配置方法,教大家在pom添加依賴的方法如何調(diào)用redis,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2021-06-06
  • 靜態(tài)方法中調(diào)用Spring注入過(guò)程解析

    靜態(tài)方法中調(diào)用Spring注入過(guò)程解析

    這篇文章主要介紹了靜態(tài)方法中調(diào)用Spring注入過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11
  • JavaWeb?使用DBUtils實(shí)現(xiàn)增刪改查方式

    JavaWeb?使用DBUtils實(shí)現(xiàn)增刪改查方式

    這篇文章主要介紹了JavaWeb?使用DBUtils實(shí)現(xiàn)增刪改查方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • 新手了解java 泛型基礎(chǔ)知識(shí)

    新手了解java 泛型基礎(chǔ)知識(shí)

    這篇文章主要給大家介紹了關(guān)于Java中泛型使用的簡(jiǎn)單方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Java具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-07-07
  • SpringCloud之Feign代理,聲明式服務(wù)調(diào)用方式

    SpringCloud之Feign代理,聲明式服務(wù)調(diào)用方式

    這篇文章主要介紹了SpringCloud之Feign代理,聲明式服務(wù)調(diào)用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03

最新評(píng)論

玛曲县| 永和县| 江口县| 瑞金市| 华坪县| 马关县| 大埔区| 新余市| 精河县| 沾化县| 西藏| 桂东县| 彭水| 菏泽市| 大冶市| 陆良县| 宝兴县| 北碚区| 洪江市| 丁青县| 松潘县| 昭平县| 前郭尔| 康平县| 玉山县| 封开县| 布拖县| 日照市| 荔浦县| 万源市| 拉孜县| 乐平市| 惠安县| 顺昌县| 依安县| 德惠市| 八宿县| 萍乡市| 东乡族自治县| 耿马| 晋江市|