使用phantomjs对网页进行截图遇到的问题

问题描述:

  1. 使用的phantomjs版本:phantomjs-2.1.1-windows
  2. 使用的截图js文件,\phantomjs-2.1.1-windows\examples\rasterize.js
  3. 使用的java驱动代码:
package mackimg;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader; /**
* @Description:根据网页地址转换成图片
* @Author: admin
* @CreateDate: 2018年6月22日
*/
public class PhantomTools {
private static String tempPath = "F:/phantomjs";// 图片保存目录
private static String BLANK = " ";
// 下面内容可以在配置文件中配置
private static String binPath = "D:/phantomjs-2.1.1-windows/bin/phantomjs.exe";// 插件引入地址
private static String jsPath = "D:/phantomjs-2.1.1-windows/rasterize.js";// js引入地址 // 执行cmd命令
public static String cmd(String imgagePath, String url) {
return binPath + BLANK + jsPath + BLANK + url + BLANK + imgagePath;
}
//关闭命令
public static void close(Process process, BufferedReader bufferedReader) throws IOException {
if (bufferedReader != null) {
bufferedReader.close();
}
if (process != null) {
process.destroy();
process = null;
}
} /**
* @param userId
* @param url
* @throws IOException
*/
public static void printUrlScreen2jpg(String url) throws IOException{
String imgagePath = tempPath+"/"+System.currentTimeMillis()+".png";//图片路径
//Java中使用Runtime和Process类运行外部程序
Process process = Runtime.getRuntime().exec(cmd(imgagePath,url));
InputStream inputStream = process.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
String tmp = "";
while ((tmp = reader.readLine()) != null) {
close(process,reader);
}
System.out.println("success");
} public static void main(String[] args) throws IOException {
String url = "https://www.baidu.com/";//以百度网站首页为例
PhantomTools.printUrlScreen2jpg(url);
}
}

以上可以参考文章:点我点我

运行之后出现异常:

Exception in thread "main" java.io.IOException: Stream closed
at java.io.BufferedReader.ensureOpen(BufferedReader.java:122)
at java.io.BufferedReader.readLine(BufferedReader.java:317)
at java.io.BufferedReader.readLine(BufferedReader.java:389)
at mackimg.PhantomTools.printUrlScreen2jpg(PhantomTools.java:48)
at mackimg.PhantomTools.main(PhantomTools.java:59)

更换网址:

String url = "http://www.cnblogs.com/han108/p/9216583.html";

能正常运行,但是后台没有图片.

更换js文件

我在网上看了别人用的另一个js文件,我命名为22.js.内容是:

var page = require('webpage').create(),
system = require('system'),
address, output, size; if (system.args.length < 3 || system.args.length > 5) {
console.log('Usage: rasterize.js URL filename');
phantom.exit(1);
} else {
address = system.args[1];
output = system.args[2];
page.viewportSize = { width: 600, height: 600 };
page.open(address, function (status) {
// 通过在页面上执行脚本获取页面的渲染高度
var bb = page.evaluate(function () {
return document.getElementsByTagName('html')[0].getBoundingClientRect();
});
// 按照实际页面的高度,设定渲染的宽高
page.clipRect = {
top: bb.top,
left: bb.left,
width: bb.width,
height: bb.height
};
// 预留一定的渲染时间
window.setTimeout(function () {
page.render(output);
page.close();
console.log('render ok');
}, 1000);
});
}
  1. 使用百度链接,抛出上面提到的异常.后台没有图片
  2. 使用cnblogs链接,抛出上面的异常,后台有图片

问题分析

不懂,不知道,去他妈的

问题解决

  1. 把代码更改为:
 while ((tmp = reader.readLine()) != null) {
}
close(process,reader);

可以解决抛出异常和后台无法获取图片的问题,但是如果使用22.js,会出现程序运行完无法自动停止的问题.

  1. 注意到,22.js文件最后几行:
 window.setTimeout(function () {
page.render(output);
page.close();
console.log('render ok');
}, 1000);
});

js文件执行完会发送一句"render ok",这就导致java代码中的 while ((tmp = reader.readLine()) != null)无法跳出,陷入阻塞状态,无法理解的是,此时自然无法执行到close(process,reader);,但是后台仍然可以获得图片.

如果此时把代码更改为:

 while ((tmp = reader.readLine()) != null) {
close(process,reader);
break;
}

此时能正常运行,后台也有图片.

  1. 按照第二种更改后的条件下,在把js文件更改为:\phantomjs-2.1.1-windows\examples\rasterize.js,程序能正常运行,后台有图片;

推荐解决办法

代码更改为:

 while ((tmp = reader.readLine()) != null) {
close(process,reader);
break;
}

phantomjs抛出IOException的更多相关文章

  1. Error:(12, 64) java: 未报告的异常错误java.io.IOException; 必须对其进行捕获或声明以便抛出

    Error:(12, 64) java: 未报告的异常错误java.io.IOException; 必须对其进行捕获或声明以便抛出 package com.test; import org.apach ...

  2. Spring异常抛出触发事务回滚

    Spring.EJB的声明式事务默认情况下都是在抛出unchecked exception后才会触发事务的回滚 /** * 如果在spring事务配置中不为切入点(如这里的切入点可以定义成test*) ...

  3. servlet 和filter 抛出404等异常

    1. servlet抛出错误代码异常,如404 public void doGet(HttpServletRequest request, HttpServletResponse response) ...

  4. YARN加载本地库抛出Unable to load native-hadoop library解决办法

    YARN加载本地库抛出Unable to load native-hadoop library解决办法 用官方的Hadoop 2.1.0-beta安装后,每次hadoop命令进去都会抛出这样一个War ...

  5. HttpClient连接池抛出大量ConnectionPoolTimeoutException: Timeout waiting for connection异常排查

    转自: http://blog.csdn.net/shootyou/article/details/6615051 今天解决了一个HttpClient的异常,汗啊,一个HttpClient使用稍有不慎 ...

  6. Spring事务异常回滚,捕获异常不抛出就不会回滚(转载) 解决了我一年前的问题

    最近遇到了事务不回滚的情况,我还考虑说JPA的事务有bug? 我想多了.......    为了打印清楚日志,很多方法我都加tyr catch,在catch中打印日志.但是这边情况来了,当这个方法异常 ...

  7. java程序中抛出异常的两种方式,及异常抛出的顺序

    在java中,会经常遇到异常,java提供了两种抛出异常的方式. 方式一: throws ,抛出具体代码中的异常,这种方式编译器都会提示,举例: public static void main(Str ...

  8. 对象反序列化时,抛出java.io.StreamCorruptedException: invalid type code: AC异常

    问题描述:在使用java.io.ObjectInputStream类的readObject()方法去读取包含有序列化了多个(两个及两个以上)类的文件时,当读取到第二个类时,会抛出题目中提到的异常. 原 ...

  9. (转)spring异常抛出触发事务回滚策略

    背景:在面试时候问到事务方法在调用过程中出现异常,是否会传递的问题,平时接触的比较少,有些懵逼. spring异常抛出触发事务回滚策略 Spring.EJB的声明式事务默认情况下都是在抛出unchec ...

随机推荐

  1. 【转载】RETE算法研究

    本文转自:http://www.ibm.com/developerworks/cn/opensource/os-drools/ RETE算法是大多数规则引擎采用的一种模式匹配算法,比如开源的Drool ...

  2. 利用DBMS_REDEFINITION包将非分区表转化成分区表

    将普通表格转化分区表的方法大致有四种: A. 通过 Export/import 方法B. 通过 Insert with a subquery 方法C. 通过 Partition Exchange 方法 ...

  3. 【解决】could not find an available, non-overlapping IPv4 address pool among the defaults to assign to the network

    在同一套环境中跑了很多个项目都是用 docker-compose的方式启动的,导致创建的自定义网络过多出现下面的报错 Error response from daemon: could not fin ...

  4. IoC和AOP扩展

    一.构造注入 二.使用p命名空间注入属性值 三.注入不同数据类型 <?xml version="1.0" encoding="UTF-8"?> &l ...

  5. Macbook下安装memcached

    参考文献: https://blog.csdn.net/weixin_41827162/article/details/82049520 感谢大佬 安装memcached需要Homebrew 注意点: ...

  6. linux 操作系统之磁盘管理

    磁盘管理 存储设备:硬盘 , U盘 , 移动硬盘 , 光盘 , 软件. 组装一台电脑 无法被修改 df -h #查看磁盘分区的情况 , 可用的. 查看磁盘或者目录的内容 df “df” 常用的 “-i ...

  7. linux操作系统的目录以及用户权权限的管理

    linux操作系统的目录以及对目录的操作 一: linux操作系统的目录结构   bin #可执行程序的安装目录 , 命令 boot #系统启动引导目录 dev #设备目录 etc #软件配置文件目录 ...

  8. python3 安装pyhanlp方法

    直接pip install pyhanlp的时候会提示缺少Microsoft Visual c++环境, 其实没有Microsoft Visual c++环境也是可以的, 可以先安装jpype1,然后 ...

  9. golang 并发执行函数func类型slice

    golang的slice支持func.使用func slice要注意func要完整描述入参出参. 如果需要执行一系列类型相同(入参出参格式相同)的函数,可以动态添加到一个slice里面.range s ...

  10. 16-oauth2-oidc-Client实现

    1-新建.net core2.1 mvc网站 2-在Startup.config文件增加相关代码, 下面代码已经配置好oidc客户端了,并设置本mvc启动ip为5009 public void Con ...