zoukankan      html  css  js  c++  java
  • 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;
            }
    
  • 相关阅读:
    mysql字符集和数据库引擎修改方法
    android 之GridView和ImageView教程
    把php代码保存到php文件实现方法
    extjs gridpanel 操作行 得到选中行的列
    SQL 分页
    vs 调试 慢 解决办法
    JS获取屏幕高度
    C#事件以及委托
    ExtJs 3.0 不兼容 IE9
    ASP.NET 获取客户端IP (无视代理)
  • 原文地址:https://www.cnblogs.com/donfaquir/p/9545161.html
Copyright © 2011-2022 走看看