• phantomjs抛出IOException


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

    问题描述:

    1. 使用的phantomjs版本:phantomjs-2.1.1-windows
    2. 使用的截图js文件,phantomjs-2.1.1-windowsexamples asterize.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 = {  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,
              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-windowsexamples asterize.js,程序能正常运行,后台有图片;

    推荐解决办法

    代码更改为:

     while ((tmp = reader.readLine()) != null) {  
            	close(process,reader);
            	break;
            }
    
  • 相关阅读:
    CF1119H
    oracle 第06章 数据字典
    oracle col命令
    oracle 第05章 SQL语句
    oracle 第04章 字符集
    oracle 第03章 体系结构
    oracle 第02章 基本操作
    oracle 第01章 安装
    oracle启动、关闭、重启脚本
    第十一周-学习进度条
  • 原文地址:https://www.cnblogs.com/donfaquir/p/9545161.html
Copyright © 2020-2023  润新知