应用场景
有个项目需要将网页上面的图表放生成的word报告中,页面上面的图表是用Echarts做的,因为要求word报告中的图表和页面上的图表保持一致,所以将页面上面的图表截图保存到数据库中,然后从数据库中查询到图片放到word报告中。为了实现自动截图保存,项目采用selenium打开chrome浏览器,访问页面后通过js截图,然后下载到文件夹中,程序运行了很长一段时间都没有问题,最近chrome浏览器自动更新到了75.0.3770版,突然发现页面截图后下载失败了,浏览器提示“下载失败”。
系统环境
服务器:windows server 2008 64位
JDK:1.8.0_161
浏览器:chrome 75.0.3770
selenium-java:3.141.59
chromedriver:75.0.3770.90
问题原因
在保存下载的图片的时候,设置了文件的保持路径,设置如下:
chromePrefs.put("download.default_directory", "E:/picture");
正是这个路径设置出现了问题,windows下必须是“\”而不是“/”,早期的chrome版本中这个路径设置后并未起作用,下载的时候使用的是chrome默认的下载路径,在最新的chrome版本中这个设置突然起作用了,因为路径错了,导致图片下载失败,正确配置如下:
chromePrefs.put("download.default_directory", "E:\\picture");
拓展知识:斜杆与反斜杆的区别
正斜杠,又称左斜杠,符号是"/";反斜杠,也称右斜杠,符号是"\"。
Unix使用斜杆/ 作为路径分隔符,web应用最开始跑在Unix系统上面,所以目前所有的网络地址都采用 斜杆/ 作为分隔符。
Windows由于使用 斜杆/ 作为DOS命令提示符的参数标志了,为了不混淆,所以采用 反斜杠\ 作为路径分隔符。所以目前windows系统上的资源管理器中都是用 反斜杠\ 作为路径分隔符。随着发展,DOS系统已经被淘汰了,命令提示符也用的很少,斜杆和反斜杠在大多数情况下可以互换,没有影响。
很多编译器使用反斜杠作为转义字符的开头,所以“\\”代表向内存中输入一个反斜杠。
示例代码
public static void main(String[] args) {
System.setProperty("webdriver.chrome.driver","C:\\ChromePortable\\chromedriver.exe");
ChromeOptions options = new ChromeOptions();
options.setBinary("C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe");
Map<String, Object> chromePrefs = new HashMap<String, Object>();
chromePrefs.put("profile.default_content_settings.popups", 0);
chromePrefs.put("download.default_directory", "E:\\picture");
chromePrefs.put("profile.content_settings.exceptions.automatic_downloads.*.setting", 1);
chromePrefs.put("download.prompt_for_download", false);
options.setExperimentalOption("prefs", chromePrefs);
ChromeDriver driver = new ChromeDriver(options);
try {
driver.get("http://172.16.0.52:8866/ljzx/reportPictureApi/toCompanyFinance?compName=北京小桔科技有限公司#/");
// 等待10000毫秒,供下载图片
Thread.sleep(10000);
driver.get("http://172.16.0.52:8866/ljzx/reportPictureApi/toCompanyLawInfo?compName=北京小桔科技有限公司#/");
// 等待15000毫秒,供下载图片
Thread.sleep(15000);
driver.quit();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}