ScreenCaptureHtmlUnitDriver.java
https://github.com/apache/incubator-zeppelin/blob/master/zeppelin-server/src/test/java/com/webautomation/ScreenCaptureHtmlUnitDriver.java
http://stackoverflow.com/questions/36254656/not-able-to-take-screenshot-using-htmlunitdriver-selenium-webdriver-java
| /* | |
| * Licensed to the Apache Software Foundation (ASF) under one or more | |
| * contributor license agreements. See the NOTICE file distributed with | |
| * this work for additional information regarding copyright ownership. | |
| * The ASF licenses this file to You under the Apache License, Version 2.0 | |
| * (the "License"); you may not use this file except in compliance with | |
| * the License. You may obtain a copy of the License at | |
| * | |
| * http://www.apache.org/licenses/LICENSE-2.0 | |
| * | |
| * Unless required by applicable law or agreed to in writing, software | |
| * distributed under the License is distributed on an "AS IS" BASIS, | |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| * See the License for the specific language governing permissions and | |
| * limitations under the License. | |
| */ | |
| package com.webautomation; | |
| import java.io.ByteArrayOutputStream; | |
| import java.io.File; | |
| import java.io.FileOutputStream; | |
| import java.io.IOException; | |
| import java.net.URL; | |
| import java.util.Collections; | |
| import java.util.HashMap; | |
| import java.util.Iterator; | |
| import java.util.LinkedList; | |
| import java.util.List; | |
| import java.util.Map; | |
| import java.util.regex.Matcher; | |
| import java.util.regex.Pattern; | |
| import java.util.zip.ZipEntry; | |
| import java.util.zip.ZipOutputStream; | |
| import org.apache.commons.io.FilenameUtils; | |
| import org.apache.commons.io.IOUtils; | |
| import org.openqa.selenium.Capabilities; | |
| import org.openqa.selenium.OutputType; | |
| import org.openqa.selenium.TakesScreenshot; | |
| import org.openqa.selenium.WebDriverException; | |
| import org.openqa.selenium.htmlunit.HtmlUnitDriver; | |
| import org.openqa.selenium.internal.Base64Encoder; | |
| import org.openqa.selenium.remote.CapabilityType; | |
| import org.openqa.selenium.remote.DesiredCapabilities; | |
| import com.gargoylesoftware.htmlunit.BrowserVersion; | |
| import com.gargoylesoftware.htmlunit.WebClient; | |
| import com.gargoylesoftware.htmlunit.WebRequest; | |
| import com.gargoylesoftware.htmlunit.WebWindow; | |
| import com.gargoylesoftware.htmlunit.html.HtmlElement; | |
| import com.gargoylesoftware.htmlunit.html.HtmlPage; | |
| import org.slf4j.Logger; | |
| import org.slf4j.LoggerFactory; | |
| /** | |
| * from https://code.google.com/p/selenium/issues/detail?id=1361 | |
| */ | |
| public class ScreenCaptureHtmlUnitDriver extends HtmlUnitDriver implements TakesScreenshot { | |
| private static Map<String, byte[]> imagesCache = Collections.synchronizedMap(new HashMap<String, byte[]>()); | |
| private static Map<String, String> cssjsCache = Collections.synchronizedMap(new HashMap<String, String>()); | |
| // http://stackoverflow.com/questions/4652777/java-regex-to-get-the-urls-from-css | |
| private final static Pattern cssUrlPattern = Pattern.compile("background(-image)?[\\s]*:[^url]*url[\\s]*\\([\\s]*([^\\)]*)[\\s]*\\)[\\s]*");// ?<url> | |
| static Logger LOGGER = LoggerFactory.getLogger(ScreenCaptureHtmlUnitDriver.class); | |
| public ScreenCaptureHtmlUnitDriver() { | |
| super(); | |
| } | |
| public ScreenCaptureHtmlUnitDriver(boolean enableJavascript) { | |
| super(enableJavascript); | |
| } | |
| public ScreenCaptureHtmlUnitDriver(Capabilities capabilities) { | |
| super(capabilities); | |
| } | |
| public ScreenCaptureHtmlUnitDriver(BrowserVersion version) { | |
| super(version); | |
| DesiredCapabilities var = ((DesiredCapabilities) getCapabilities()); | |
| var.setCapability(CapabilityType.TAKES_SCREENSHOT, true); | |
| } | |
| @Override | |
| @SuppressWarnings("unchecked") | |
| public <X> X getScreenshotAs(OutputType<X> target) throws WebDriverException { | |
| byte[] archive = new byte[0]; | |
| try { | |
| archive = downloadCssAndImages(getWebClient(), (HtmlPage) getCurrentWindow().getEnclosedPage()); | |
| } catch (Exception e) { | |
| LOGGER.error("Exception in ScreenCaptureHtmlUnitDriver while getScreenshotAs ", e); | |
| } | |
| if(target.equals(OutputType.BASE64)){ | |
| return target.convertFromBase64Png(new Base64Encoder().encode(archive)); | |
| } | |
| if(target.equals(OutputType.FILE)){ | |
| File f = new File("screen.tmp"); | |
| try { | |
| FileOutputStream scr = new FileOutputStream(f); | |
| scr.write(archive); | |
| scr.close(); | |
| } catch (IOException e) { | |
| throw new WebDriverException(e); | |
| } | |
| return (X) f; | |
| } | |
| return (X) archive; | |
| } | |
| // http://stackoverflow.com/questions/2244272/how-can-i-tell-htmlunits-webclient-to-download-images-and-css | |
| protected byte[] downloadCssAndImages(WebClient webClient, HtmlPage page) throws Exception { | |
| WebWindow currentWindow = webClient.getCurrentWindow(); | |
| Map<String, String> urlMapping = new HashMap<String, String>(); | |
| Map<String, byte[]> files = new HashMap<String, byte[]>(); | |
| WebWindow window = null; | |
| try { | |
| window = webClient.getWebWindowByName(page.getUrl().toString()+"_screenshot"); | |
| webClient.getPage(window, new WebRequest(page.getUrl())); | |
| } catch (Exception e) { | |
| LOGGER.error("Exception in ScreenCaptureHtmlUnitDriver while downloadCssAndImages ", e); | |
| window = webClient.openWindow(page.getUrl(), page.getUrl().toString()+"_screenshot"); | |
| } | |
| String xPathExpression = "//*[name() = 'img' or name() = 'link' and (@type = 'text/css' or @type = 'image/x-icon') or @type = 'text/javascript']"; | |
| List<?> resultList = page.getByXPath(xPathExpression); | |
| Iterator<?> i = resultList.iterator(); | |
| while (i.hasNext()) { | |
| try { | |
| HtmlElement el = (HtmlElement) i.next(); | |
| String resourceSourcePath = el.getAttribute("src").equals("") ? el.getAttribute("href") : el | |
| .getAttribute("src"); | |
| if (resourceSourcePath == null || resourceSourcePath.equals("")) | |
| continue; | |
| URL resourceRemoteLink = page.getFullyQualifiedUrl(resourceSourcePath); | |
| String resourceLocalPath = mapLocalUrl(page, resourceRemoteLink, resourceSourcePath, urlMapping); | |
| urlMapping.put(resourceSourcePath, resourceLocalPath); | |
| if (!resourceRemoteLink.toString().endsWith(".css")) { | |
| byte[] image = downloadImage(webClient, window, resourceRemoteLink); | |
| files.put(resourceLocalPath, image); | |
| } else { | |
| String css = downloadCss(webClient, window, resourceRemoteLink); | |
| for (String cssImagePath : getLinksFromCss(css)) { | |
| URL cssImagelink = page.getFullyQualifiedUrl(cssImagePath.replace("\"", "").replace("\'", "") | |
| .replace(" ", "")); | |
| String cssImageLocalPath = mapLocalUrl(page, cssImagelink, cssImagePath, urlMapping); | |
| files.put(cssImageLocalPath, downloadImage(webClient, window, cssImagelink)); | |
| } | |
| files.put(resourceLocalPath, replaceRemoteUrlsWithLocal(css, urlMapping) | |
| .replace("resources/", "./").getBytes()); | |
| } | |
| } catch (Exception e) { | |
| LOGGER.error("Exception in ScreenCaptureHtmlUnitDriver while resultList.iterator ", e); | |
| } | |
| } | |
| String pagesrc = replaceRemoteUrlsWithLocal(page.getWebResponse().getContentAsString(), urlMapping); | |
| files.put("page.html", pagesrc.getBytes()); | |
| webClient.setCurrentWindow(currentWindow); | |
| return createZip(files); | |
| } | |
| String downloadCss(WebClient webClient, WebWindow window, URL resourceUrl) throws Exception { | |
| if (cssjsCache.get(resourceUrl.toString()) == null) { | |
| cssjsCache.put(resourceUrl.toString(), webClient.getPage(window, new WebRequest(resourceUrl)) | |
| .getWebResponse().getContentAsString()); | |
| } | |
| return cssjsCache.get(resourceUrl.toString()); | |
| } | |
| byte[] downloadImage(WebClient webClient, WebWindow window, URL resourceUrl) throws Exception { | |
| if (imagesCache.get(resourceUrl.toString()) == null) { | |
| imagesCache.put( | |
| resourceUrl.toString(), | |
| IOUtils.toByteArray(webClient.getPage(window, new WebRequest(resourceUrl)).getWebResponse() | |
| .getContentAsStream())); | |
| } | |
| return imagesCache.get(resourceUrl.toString()); | |
| } | |
| public static byte[] createZip(Map<String, byte[]> files) throws IOException { | |
| ByteArrayOutputStream bos = new ByteArrayOutputStream(); | |
| ZipOutputStream zipfile = new ZipOutputStream(bos); | |
| Iterator<String> i = files.keySet().iterator(); | |
| String fileName = null; | |
| ZipEntry zipentry = null; | |
| while (i.hasNext()) { | |
| fileName = i.next(); | |
| zipentry = new ZipEntry(fileName); | |
| zipfile.putNextEntry(zipentry); | |
| zipfile.write(files.get(fileName)); | |
| } | |
| zipfile.close(); | |
| return bos.toByteArray(); | |
| } | |
| List<String> getLinksFromCss(String css) { | |
| List<String> result = new LinkedList<String>(); | |
| Matcher m = cssUrlPattern.matcher(css); | |
| while (m.find()) { // find next match | |
| result.add( m.group(2)); | |
| } | |
| return result; | |
| } | |
| String replaceRemoteUrlsWithLocal(String source, Map<String, String> replacement) { | |
| for (String object : replacement.keySet()) { | |
| // background:url(http://org.com/images/image.gif) | |
| source = source.replace(object, replacement.get(object)); | |
| } | |
| return source; | |
| } | |
| String mapLocalUrl(HtmlPage page, URL link, String path, Map<String, String> replacementToAdd) throws Exception { | |
| String resultingFileName = "resources/" + FilenameUtils.getName(link.getFile()); | |
| replacementToAdd.put(path, resultingFileName); | |
| return resultingFileName; | |
| } | |
| } |
ScreenCaptureHtmlUnitDriver.java的更多相关文章
- Spark案例分析
一.需求:计算网页访问量前三名 import org.apache.spark.rdd.RDD import org.apache.spark.{SparkConf, SparkContext} /* ...
- 故障重现(内存篇2),JAVA内存不足导致频繁回收和swap引起的性能问题
背景起因: 记起以前的另一次也是关于内存的调优分享下 有个系统平时运行非常稳定运行(没经历过大并发考验),然而在一次活动后,人数并发一上来后,系统开始卡. 我按经验开始调优,在每个关键步骤的加入如 ...
- Elasticsearch之java的基本操作一
摘要 接触ElasticSearch已经有一段了.在这期间,遇到很多问题,但在最后自己的不断探索下解决了这些问题.看到网上或多或少的都有一些介绍ElasticSearch相关知识的文档,但个人觉得 ...
- 论:开发者信仰之“天下IT是一家“(Java .NET篇)
比尔盖茨公认的IT界领军人物,打造了辉煌一时的PC时代. 2008年,史蒂夫鲍尔默接替了盖茨的工作,成为微软公司的总裁. 2013年他与微软做了最后的道别. 2013年以后,我才真正看到了微软的变化. ...
- 故障重现, JAVA进程内存不够时突然挂掉模拟
背景,服务器上的一个JAVA服务进程突然挂掉,查看产生了崩溃日志,如下: # Set larger code cache with -XX:ReservedCodeCacheSize= # This ...
- 死磕内存篇 --- JAVA进程和linux内存间的大小关系
运行个JAVA 用sleep去hold住 package org.hjb.test; public class TestOnly { public static void main(String[] ...
- 【小程序分享篇 一 】开发了个JAVA小程序, 用于清除内存卡或者U盘里的垃圾文件非常有用
有一种场景, 手机内存卡空间被用光了,但又不知道哪个文件占用了太大,一个个文件夹去找又太麻烦,所以我开发了个小程序把手机所有文件(包括路径下所有层次子文件夹下的文件)进行一个排序,这样你就可以找出哪个 ...
- Java多线程基础学习(二)
9. 线程安全/共享变量——同步 当多个线程用到同一个变量时,在修改值时存在同时修改的可能性,而此时该变量只能被赋值一次.这就会导致出现“线程安全”问题,这个被多个线程共用的变量称之为“共享变量”. ...
- Java多线程基础学习(一)
1. 创建线程 1.1 通过构造函数:public Thread(Runnable target, String name){} 或:public Thread(Runnable target ...
随机推荐
- UVa 1395 (最小生成树)
题目链接:http://vjudge.net/problem/41567/origin 本来想着m^2的复杂度撑不住,对于这种擦着边的复杂度就好慌. 首先对所有的边排个序,然后枚举每个可以构成生成树的 ...
- Mayor's posters问题处理
题目的感悟: /*这道题的想法是先开一个数组,先构造一颗线段树,然后每次都进行一次更新最后我们在访问的时候只要看最外层还剩下那些数字,对他们进行统计然后将结果返回即可.这道题的难度本来是不大的,思路非 ...
- HDU2504:又见GCD
Problem Description 有三个正整数a,b,c(0<a,b,c<10^6),其中c不等于b.若a和c的最大公约数为b,现已知a和b,求满足条件的最小的c. Input ...
- 构造DataTable
手动构造一个DataTable: DataTable dt = new DataTable(); dt.Columns.Add("ID", typeof(string)); dt. ...
- js获取tr,td内容并排序
如题 <!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.o ...
- watch命令
watch是一个非常实用的命令,基本所有的Linux发行版都带有这个小工具,如同名字一样,watch可以帮你监测一个命令的运行结果,省得你一遍遍的手动运行.在Linux下,watch是周期性的执行下个 ...
- 转载 C语言中volatile关键字的作用
一.前言 1.编译器优化介绍: 由于内存访问速度远不及CPU处理速度,为提高机器整体性能,在硬件上引入硬件高速缓存Cache,加速对内存的访问.另外在现代CPU中指令的执行并不一定严格按照顺序执行,没 ...
- postfix队列管理
队列管理单元的服务器程序--qmgr,是整个postfix系统的中心枢纽.所有邮件,包括等待送出与从外界收进来的,都必须通过队列.了解队列的运行原理以及postfix如何处理队列,有助于你解决问题. ...
- SVN-svn path not found: 404 Not Found
报错信息是本地找不到文件 因为我直接移动了项目中的java文件到别的目录,在SVN看来相当于变相的删掉了一个目录的文件,在另外一个目录新增文件, 但是移动文件SVN是不会做删除记录到日志文件中的,所以 ...
- 修改config.php配置
$data=array( "name"=>"222222", "tel"=>159131, "address" ...