<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-exec</artifactId> <version>1.3</version> </dependency> <dependency> <groupId>com.github.abel533</groupId> <artifactId>ECharts</artifactId> <version>3.0.0.2</version> </dependency> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> </dependency> <!-- Open API在線文檔 --> <dependency> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-ui</artifactId> <version>1.3.4</version> </dependency> <!-- selenium測試工具使用的phantomjs驅動 --> <dependency> <groupId>com.codeborne</groupId> <artifactId>phantomjsdriver</artifactId> <version>1.4.4</version> </dependency>
function Base64() { // private property _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; // public method for encoding this.encode = function (input) { var output = ""; var chr1, chr2, chr3, enc1, enc2, enc3, enc4; var i = 0; input = _utf8_encode(input); while (i < input.length) { chr1 = input.charCodeAt(i++); chr2 = input.charCodeAt(i++); chr3 = input.charCodeAt(i++); enc1 = chr1 >> 2; enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); enc4 = chr3 & 63; if (isNaN(chr2)) { enc3 = enc4 = 64; } else if (isNaN(chr3)) { enc4 = 64; } output = output + _keyStr.charAt(enc1) + _keyStr.charAt(enc2) + _keyStr.charAt(enc3) + _keyStr.charAt(enc4); } return output; } // public method for decoding this.decode = function (input) { var output = ""; var chr1, chr2, chr3; var enc1, enc2, enc3, enc4; var i = 0; input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); while (i < input.length) { enc1 = _keyStr.indexOf(input.charAt(i++)); enc2 = _keyStr.indexOf(input.charAt(i++)); enc3 = _keyStr.indexOf(input.charAt(i++)); enc4 = _keyStr.indexOf(input.charAt(i++)); chr1 = (enc1 << 2) | (enc2 >> 4); chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); chr3 = ((enc3 & 3) << 6) | enc4; output = output + String.fromCharCode(chr1); if (enc3 != 64) { output = output + String.fromCharCode(chr2); } if (enc4 != 64) { output = output + String.fromCharCode(chr3); } } output = _utf8_decode(output); return output; } // private method for UTF-8 encoding _utf8_encode = function (string) { string = string.replace(/\r\n/g,"\n"); var utftext = ""; for (var n = 0; n < string.length; n++) { var c = string.charCodeAt(n); if (c < 128) { utftext += String.fromCharCode(c); } else if((c > 127) && (c < 2048)) { utftext += String.fromCharCode((c >> 6) | 192); utftext += String.fromCharCode((c & 63) | 128); } else { utftext += String.fromCharCode((c >> 12) | 224); utftext += String.fromCharCode(((c >> 6) & 63) | 128); utftext += String.fromCharCode((c & 63) | 128); } } return utftext; } // private method for UTF-8 decoding _utf8_decode = function (utftext) { var string = ""; var i = 0; var c = c1 = c2 = 0; while ( i < utftext.length ) { c = utftext.charCodeAt(i); if (c < 128) { string += String.fromCharCode(c); i++; } else if((c > 191) && (c < 224)) { c2 = utftext.charCodeAt(i+1); string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); i += 2; } else { c2 = utftext.charCodeAt(i+1); c3 = utftext.charCodeAt(i+2); string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); i += 3; } } return string; } } // ///////////////////////////////// system = require('system'); // 獲取參數 //傳遞過來的數據 var base64JsonStr = system.args[1]; //截屏文件保存路徑 var screenshotPath = system.args[2]; // 將base64解密 var paramsJsonStr = new Base64().decode(base64JsonStr) ; // 轉換爲json對象 var jsonObj = JSON.parse(paramsJsonStr); //Echarts的Option參數 var option = jsonObj.option ; //截圖屏幕的寬高值 var clipWidth = jsonObj.clipWidth ; var clipHeight = jsonObj.clipHeight ; function Convert(params){ this.params = params ; this.external = { JQUERY3 : 'jquery-1.9.0rc1.js', ECHARTS3 : 'echarts3.8.4.min.js' }; this.page = require('webpage').create(); // 客戶端 this.page.viewportSize = { width: clipWidth, height: clipHeight }; // 日誌監聽console,防止有些內部方法控制檯不顯示 this.page.onConsoleMessage = function(msg, lineNum, sourceId) { console.log('CONSOLE: ' + msg + ' (from line #' + lineNum + ' in "' + sourceId + '")'); }; var instance = this ; this.page.onError = function(msg, trace) { var msgStack = ['PHANTOM ERROR: ' + msg]; if (trace && trace.length) { msgStack.push('TRACE:'); trace.forEach(function(t) { msgStack.push(' -> ' + (t.file || t.sourceURL) + ': ' + t.line + (t.function ? ' (in function ' + t.function +')' : '')); }); } console.error(msgStack.join('\n')); //失敗,返回錯誤信息 instance.output("", false, msg); }; this.page.onLoadStarted = function() { console.log('Start loading...'); }; this.page.onLoadFinished = function (status) { console.log('Loading finished.'); }; // 加載資源監聽 this.page.onResourceReceived = function (res) { console.log('Response (#' + res.id + ', stage =' + res.stage + ', code = ' + res.status + ', redirect= ' + res.redirectURL + ') '); }; console.log("實例化完成"); } Convert.prototype.init = function(){ var instance = this ; instance.page.open("about:blank", function(status) { // 把指定的外部JS文件注入到當前環境 var hasJquery = instance.page.injectJs(instance.external.JQUERY3); var hasEchart = instance.page.injectJs(instance.external.ECHARTS3); // 檢查js是否引用成功 if (!hasJquery || !hasEchart) { instance.output("Could not found " + instance.external.JQUERY3 + " or " + instance.external.ECHARTS3, false); } // 第一個爲交互執行的方法; 第二個爲傳遞給函數的參數 instance.page.evaluate(instance.createEchartsDom,instance.params); // 定義剪切範圍,若是定義則截取全屏 instance.page.clipRect = { top : 0, left : 0, width : clipWidth, height : clipHeight }; // 渲染 var result = instance.render(); // 成功輸出,返回圖片或其餘信息 instance.output(result, true); }); } Convert.prototype.render = function(){ var instance = this ; switch (instance.params.type) { case 'file': instance.page.render(screenshotPath); return screenshotPath; case 'base64': default: var base64 = instance.page.renderBase64('PNG'); return base64; } } Convert.prototype.output = function(content, success, msg) { var instance = this ; console.log(success ? "[SUCCESS]:" : "[ERROR]:" + content); instance.page.close(); instance.exit(instance.params); }; Convert.prototype.exit = function (params) { console.log("退出phantom") ; phantom.exit() }; // // 建立eCharts Dom層 // @param params 參數 // params.opt // params.width // params.height // params.outfile // params.type = 'PNG' // Convert.prototype.createEchartsDom = function(params) { var instance = this ; var options = params.option ; // 動態加載js,獲取options數據 $('<script>') .attr('type', 'text/javascript') .appendTo(document.head); // 取消動畫,不然生成圖片過快,會出現無數據 if (options !== undefined) { options.animation = false; } // body背景設置爲白色 $(document.body).css('backgroundColor', 'white'); // echarts容器 var container = $("<div>") .attr('id', 'container') .css({ width : params.clipWidth, height : params.clipHeight }).appendTo(document.body); var eChart = echarts.init(container[0]); eChart.setOption(options); } ; // 構建,入口 new Convert(jsonObj).init();
/** * 進行屏幕的截屏操做 */ public interface ScreenshotProvider { /** * 根據參數判斷是否支持 */ boolean support(ScreenshotParam param); /** * 執行屏幕裁剪 */ ScreenshotResult clip(ScreenshotParam param) throws Exception; }
public class ScreenshotParam { /** * 訪問的url地址;格式如: * 1:about:blank <br /> * 2:file///:/path/to/demo.html <br /> * 3:https://www.baidu.com <br /> * */ private String url ; // 剪裁寬度 private Integer clipWidth = 500 ; // 剪裁高度 private Integer clipHeight = 400 ; }
public class ScreenshotResult { // 截圖保存路徑 private String screenshotPath; public ScreenshotResult() { } public ScreenshotResult(ScreenshotResult result) { if(result == null) { return ; } this.screenshotPath = result.getScreenshotPath() ; } public ScreenshotResult(String screenshotPath) { this.screenshotPath = screenshotPath; } }
@Component public class ScreenshotManager { @Autowired public List<ScreenshotProvider> providers = new ArrayList<ScreenshotProvider>() ; /** * 執行屏幕裁剪 * @throws Exception * */ public ScreenshotResult clip(ScreenshotParam param) throws Exception { for(ScreenshotProvider provider:providers) { if(!provider.support(param)) { continue ; } return provider.clip(param) ; } return null ; } }
/** * 經過Phantomjs來執行JavaScript文件 <br /> * github.com/ariya/phantomjs/tree/master/examples */ public abstract class PhantomjsScreenshotProvider implements ScreenshotProvider { private Logger log = LoggerFactory.getLogger(PhantomjsScreenshotProvider.class); protected static String BLANK = " "; @Value("${screenshotDir:}") protected String screenshotDir; @Value("${phantomjsPath:}") protected String phantomjsPath; // rasterize.js protected String jsFilePath; @PostConstruct public void init() { if (StringUtils.isBlank(screenshotDir)) { try { File classPathDir = ResourceUtils.getFile(ResourceUtils.CLASSPATH_URL_PREFIX); File dir = new File(classPathDir.getAbsolutePath() + "/screenshot/phantomjs/echarts/images"); if (!dir.exists() || !dir.isDirectory()) { dir.mkdirs(); } screenshotDir = dir.getAbsolutePath(); log.info("screenshotDir:{}", screenshotDir); } catch (FileNotFoundException e) { e.printStackTrace(); } } if (StringUtils.isBlank(phantomjsPath)) { try { File exeFile = null; if (OSUtil.isLinux() || OSUtil.isMacOSX()) { exeFile = ResourceUtils .getFile(ResourceUtils.CLASSPATH_URL_PREFIX + "drivers/phantomjs/v2.1.1/linux64/phantomjs"); } else { exeFile = ResourceUtils.getFile( ResourceUtils.CLASSPATH_URL_PREFIX + "drivers/phantomjs/v2.1.1/window/phantomjs.exe"); } phantomjsPath = exeFile.getAbsolutePath(); log.info("phantomjsPath:{}", phantomjsPath); } catch (FileNotFoundException e) { e.printStackTrace(); } } if (StringUtils.isBlank(jsFilePath)) { try { // 執行的JS文件路徑 File jsFile = ResourceUtils.getFile("classpath:static/js/rasterize.js"); // 生成的圖片名稱 jsFilePath = jsFile.getAbsolutePath(); log.info("jsFilePath:{}", jsFilePath); } catch (FileNotFoundException e) { e.printStackTrace(); } } } // 生成圖片的所存放路徑 protected String getRandomImagePath() { String outPath = screenshotDir + File.separator + new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + "-" + new Random().nextInt() + ".png"; return outPath; } // 執行cmd命令 protected String commandLine(String url, String screenshotPath) { return phantomjsPath + BLANK + jsFilePath + BLANK + url + BLANK + screenshotPath; } protected void exeCommandLine(String commandLine) throws IOException { // Java中使用Runtime和Process類運行外部程序 Process process = Runtime.getRuntime().exec(commandLine); InputStream inputStream = process.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); String tmp = ""; StringBuffer sb = new StringBuffer(); while ((tmp = reader.readLine()) != null) { sb.append(tmp); } close(process, reader); } // 關閉命令 protected void close(Process process, BufferedReader bufferedReader) throws IOException { if (bufferedReader != null) { bufferedReader.close(); } if (process != null) { process.destroy(); process = null; } } public String getScreenshotDir() { return screenshotDir; } public void setScreenshotDir(String screenshotDir) { this.screenshotDir = screenshotDir; } public String getPhantomjsPath() { return phantomjsPath; } public void setPhantomjsPath(String phantomjsPath) { this.phantomjsPath = phantomjsPath; } public String getJsFilePath() { return jsFilePath; } public void setJsFilePath(String jsFilePath) { this.jsFilePath = jsFilePath; } }
@Component public class EchartsScreenshotProvider extends PhantomjsScreenshotProvider { private Logger log = LoggerFactory.getLogger(EchartsScreenshotProvider.class); @PostConstruct public void init() { if (StringUtils.isBlank(jsFilePath)) { try { // 執行的JS文件路徑 File jsFile = ResourceUtils.getFile("classpath:static/js/echarts-screenshot.js"); // 生成的圖片名稱 jsFilePath = jsFile.getAbsolutePath(); log.info("jsFilePath:{}", jsFilePath); } catch (FileNotFoundException e) { e.printStackTrace(); } } super.init(); } @Override public boolean support(ScreenshotParam param) { return param instanceof EchartsScreenshotParam; } @Override public ScreenshotResult clip(ScreenshotParam param) throws Exception { EchartsScreenshotParam echartsScreenshotParam = (EchartsScreenshotParam) param; if (echartsScreenshotParam == null || echartsScreenshotParam.getOption() == null) { throw new Exception("參數不能爲空") ; } if(StringUtils.isBlank(jsFilePath)) { throw new Exception("執行的js文件不能爲空") ; } //屏幕截圖的保存位置 String screenshotPath = getRandomImagePath(); // 實例化 Gson gson = new Gson(); // 將map轉成JSON String paramsJsonStr = gson.toJson(echartsScreenshotParam); Encoder encoder = Base64.getEncoder(); // 轉換爲base64編碼是爲了防止執行指令的時候出問題 String base64Str = encoder.encodeToString(paramsJsonStr.getBytes("UTF-8")); String[] args = new String[3]; args[0] = jsFilePath; args[1] = base64Str; args[2] = screenshotPath; // 執行腳本 try { CommandExecUtil.exec(phantomjsPath, args, null) ; } catch (Exception e) { throw e; } return new ScreenshotResult(screenshotPath); } }
/** * 使用Echarts的數據來渲染出圖片並截取 */ public class EchartsScreenshotParam extends ScreenshotParam { // echart的Option public Option option; public String type = "file"; public String getType() { return type; } public void setType(String type) { this.type = type; } public Option getOption() { return option; } public void setOption(Option option) { this.option = option; } }
public class CommandExecUtil { /** * @param commandLine * 須要執行的命令行,例如:"AcroRd32.exe /p /h c://file.pdf" */ public static int exec(String commandLine) throws Exception { CommandLine cmdLine = CommandLine.parse(commandLine); DefaultExecutor executor = new DefaultExecutor(); int exitValue = executor.execute(cmdLine); return exitValue; } /** * @param command * 命令,例如:AcroRd32.exe * @param args * 參數,例如:/C , /p, /h */ public static int exec(String command, String[] args, Map<String, ?> substitutionMap) throws Exception { CommandLine cmdLine = new CommandLine(command); if (args != null && args.length > 0) { for (String arg : args) { cmdLine.addArgument(arg); } } if (substitutionMap != null) { cmdLine.setSubstitutionMap(substitutionMap); } DefaultExecutor executor = new DefaultExecutor(); // executor.setExitValue(1); // ExecuteWatchdog watchdog = new ExecuteWatchdog(60000); // executor.setWatchdog(watchdog); int exitValue = executor.execute(cmdLine); return exitValue; } }
@Tag(name = "屏幕截圖", description = "截屏測試控制器") @RestController @RequestMapping(path = "/screenshot") public class ScreenshotController { @Autowired private ScreenshotManager manager; @Operation(summary = "使用Freemarker生成html並截圖", description = "", tags = { "屏幕截圖" }) @GetMapping(path = "/freemarker") public ScreenshotResult freemarkerScreenshot(String templateName) throws Exception { FreemarkerSeleniumScreenshotParam param = new FreemarkerSeleniumScreenshotParam(DriverTypeEnum.PhantomJS); param.setTemplatePath(templateName); param.setClipWidth(600); param.setClipHeight(500); return manager.clip(param); } @Operation(summary = "使用Selenium截圖", description = "", tags = { "屏幕截圖" }) @GetMapping(path = "/selenium/phantomjs") public ScreenshotResult seleniumScreenshot(String url) throws Exception { SeleniumScreenshotParam param = new SeleniumScreenshotParam(DriverTypeEnum.PhantomJS); param.setUrl(url); return manager.clip(param); } @Operation(summary = "使用phantomjs進行echarts截圖", description = "", tags = { "屏幕截圖" }) @GetMapping(path = "/phantomjs/echarts") public ScreenshotResult phantomjsEchartsScreenshot() throws Exception { EchartsScreenshotParam param = new EchartsScreenshotParam(); param.setOption(getEchartOption()); return manager.clip(param); } public Option getEchartOption() { Option option = new Option(); option.legend("this is the legend"); option.toolbox().show(true).feature(Tool.mark, Tool.dataView, new MagicType(Magic.line, Magic.bar), Tool.restore, Tool.saveAsImage); option.calculable(true); option.tooltip().trigger(Trigger.axis).formatter("Temperature : <br/>{b}km : {c}°C"); ValueAxis valueAxis = new ValueAxis(); valueAxis.axisLabel().formatter("{value} °C"); option.xAxis(valueAxis); CategoryAxis categoryAxis = new CategoryAxis(); categoryAxis.axisLine().onZero(false); categoryAxis.axisLabel().formatter("{value} km"); categoryAxis.boundaryGap(false); categoryAxis.data(0, 10, 20, 30, 40, 50, 60, 70, 80); option.yAxis(categoryAxis); Line line = new Line(); line.smooth(true).name("line ssss").data(15, -50, -56.5, -46.5, -22.1, -2.5, -27.7, -55.7, -76.5).itemStyle() .normal().lineStyle().shadowColor("rgba(0,0,0,0.4)"); option.series(line); return option; } public ScreenshotManager getManager() { return manager; } public void setManager(ScreenshotManager manager) { this.manager = manager; } }
以上是經過命令行的方式啓動phantomjs並執行JS文件後將Echarts圖片截取下來的過程;除了這種方式外,還能夠經過selenium來配合完成,例如如下代碼:javascript
/** * Some of the examples of Headless Drivers include <br /> * 1,HtmlUnit <br /> * 2,Ghost <br /> * 3,PhantomJS <br /> * 4,ZombieJS <br /> * 5,Watir-webdriver <br /> * */ @Component public class SeleniumPhantomjsScreenshotProvider implements ScreenshotProvider { private static final Logger log = LoggerFactory.getLogger(SeleniumPhantomjsScreenshotProvider.class); @Value("${screenshotDir:}") protected String screenshotDir; @Value("${phantomjsPath:}") protected String phantomjsPath; @PostConstruct public void init() { if (StringUtils.isBlank(screenshotDir)) { try { File classPathDir = ResourceUtils.getFile(ResourceUtils.CLASSPATH_URL_PREFIX); File dir = new File(classPathDir.getAbsolutePath() + "/screenshot/selenium/phantomjs/images"); if (!dir.exists() || !dir.isDirectory()) { dir.mkdirs(); } screenshotDir = dir.getAbsolutePath(); log.info("screenshotDir:{}", screenshotDir); } catch (FileNotFoundException e) { e.printStackTrace(); } } if (StringUtils.isBlank(phantomjsPath)) { try { File exeFile = null; if (OSUtil.isLinux() || OSUtil.isMacOSX()) { exeFile = ResourceUtils .getFile(ResourceUtils.CLASSPATH_URL_PREFIX + "drivers/phantomjs/v2.1.1/linux64/phantomjs"); } else { exeFile = ResourceUtils.getFile( ResourceUtils.CLASSPATH_URL_PREFIX + "drivers/phantomjs/v2.1.1/window/phantomjs.exe"); } phantomjsPath = exeFile.getAbsolutePath(); log.info("phantomjsPath:{}", phantomjsPath); } catch (FileNotFoundException e) { e.printStackTrace(); } } } // 生成圖片的所存放路徑 protected String getRandomImagePath() { String outPath = screenshotDir + File.separator + new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + "-" + new Random().nextInt() + ".png"; return outPath; } @Override public boolean support(ScreenshotParam param) { if(!(param instanceof SeleniumScreenshotParam)) { return false ; } SeleniumScreenshotParam params = (SeleniumScreenshotParam)param ; return params.getDriverType() == DriverTypeEnum.PhantomJS ; } @Override public ScreenshotResult clip(ScreenshotParam param) throws Exception { return new ScreenshotResult(getPicByPhantomjs(param)); } private String getPicByPhantomjs(ScreenshotParam param) throws Exception { log.warn("使用phantomjs截圖連接:{}", param.getUrl()); // 定義圖片存儲路徑 DesiredCapabilities capabilities = new DesiredCapabilities(BrowserType.PHANTOMJS, "", Platform.ANY); WebDriver driver = null; try { // ssl證書支持 capabilities.setCapability(CapabilityType.ACCEPT_SSL_CERTS, true); // 截屏支持 capabilities.setCapability(CapabilityType.TAKES_SCREENSHOT, true); // css搜索支持 capabilities.setCapability(CapabilityType.SUPPORTS_FINDING_BY_CSS, true); // js支持 capabilities.setJavascriptEnabled(true); capabilities.setCapability(CapabilityType.SUPPORTS_LOCATION_CONTEXT, true); capabilities.setCapability(CapabilityType.SUPPORTS_NETWORK_CONNECTION, true); // defines whether to execute the script in the page or not (defaults to true). capabilities.setCapability("phantomjs.page.settings.javascriptEnabled", true); // defines whether to load the inlined images or not (defaults to true) capabilities.setCapability("phantomjs.page.settings.loadImages", true); // defines whether local resource (e.g. from file) can access remote URLs or not // (defaults to false). capabilities.setCapability("phantomjs.page.settings.localToRemoteUrlAccessEnabled", true); // sets the user name used for HTTP authentication. // capabilities.setCapability("phantomjs.page.settings.userName", ""); // sets the password used for HTTP authentication. // capabilities.setCapability("phantomjs.page.settings.password", ""); // defines whether web security should be enabled or not (defaults to true). capabilities.setCapability("phantomjs.page.settings.webSecurityEnabled", true); // (in milli-secs) defines the timeout after which any resource requested will // stop trying and proceed with other parts of the page. // capabilities.setCapability("phantomjs.page.settings.resourceTimeout", 5000); capabilities.setCapability("phantomjs.page.settings.userAgent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:64.0) Gecko/20100101 Firefox/64.0"); capabilities.setCapability("phantomjs.page.customHeaders.User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:64.0) Gecko/20100101 Firefox/64.0"); // 驅動支持(第二參數代表的是你的phantomjs引擎-例如phantomjs.exe所在的路徑) capabilities.setCapability(PhantomJSDriverService.PHANTOMJS_EXECUTABLE_PATH_PROPERTY, phantomjsPath); // 建立***面瀏覽器對象 driver = new PhantomJSDriver(capabilities); driver.manage().window().setSize(new Dimension(param.getClipWidth(), param.getClipHeight())); // 設置隱性等待(做用於全局) driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS).pageLoadTimeout(20, TimeUnit.SECONDS); // 發起請求 try { driver.get(param.getUrl()); } catch (Exception e) { log.error("開發地址 {} 發生異常:{}", param.getUrl(), e.getMessage()); throw e; } try { Thread.sleep(4 * 1000); } catch (InterruptedException e) { } // 指定了OutputType.FILE作爲參數傳遞給getScreenshotAs()方法,其含義是將截取的屏幕以文件形式返回。 File srcFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE); try { Thread.sleep(2 * 1000); } catch (InterruptedException e) { } // 利用FileUtils工具類的copyFile()方法保存getScreenshotAs()返回的文件對象 String outFilePath = this.getRandomImagePath(); FileUtils.copyFile(srcFile, new File(outFilePath)); return outFilePath; } catch (Exception e) { log.error("使用phantomjs截圖時異常:{}", e.getMessage()); throw e; } finally { if (driver != null) { driver.close(); driver.quit(); } } } protected void scrollWindow(JavascriptExecutor js) { // 頁面下滑10次,每次下滑加載2s for (int i = 0; i < 10; i++) { js.executeScript("window.scrollBy(0,1000)"); // 睡眠2s等js加載完成 try { Thread.sleep(2 * 1000); } catch (InterruptedException e) { } } } protected void clickAction(PhantomJSDriver driver, String elementClassName) { if (elementExist(driver, By.className(elementClassName))) { WebElement inputBox = driver.findElement(By.className(elementClassName)); Actions action = new Actions(driver); action.click(inputBox).build().perform(); // 元素點擊 後等待加載 try { Thread.sleep(2 * 1000); } catch (InterruptedException e) { } } } private boolean elementExist(PhantomJSDriver driver, By by) { return driver.findElement(by) == null ? false : true; } }
public class SeleniumScreenshotParam extends ScreenshotParam{ //使用的驅動器的類型 private DriverTypeEnum driverType ; public SeleniumScreenshotParam(DriverTypeEnum driverType) { this.driverType = driverType ; } public DriverTypeEnum getDriverType() { return driverType; } }
public enum DriverTypeEnum { PhantomJS,HtmlUnit,ZombieJS; }