phantomjs抛出IOException

简介: 使用phantomjs对网页进行截图遇到的问题问题描述:使用的phantomjs版本:phantomjs-2.1.1-windows使用的截图js文件,\phantomjs-2.1.1-windows\examples\rasterize.

使用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;
        }
目录
相关文章
|
移动开发 前端开发 JavaScript
一文讲透支付宝沙箱的基本应用
沙箱环境是支付宝开放平台为开发者提供的与生产环境完全隔离的联调测试环境,开发者在沙箱环境中完成的接口调用不会对生产环境中的数据造成任何影响。沙箱为开放的产品提供有限功能范围的支持,可以覆盖产品的绝大部分核心链路和对接逻辑,便于开发者快速学习/尝试/开发/调试。沙箱环境会自动完成或忽略一些场景的业务门槛,例如:开发者无需等待产品开通,即可直接在沙箱环境调用接口,使得开发集成工作可以与业务流程并行,从而提高项目整体的交付效率。......
3347 0
一文讲透支付宝沙箱的基本应用
|
11月前
|
传感器 算法 物联网
基于STM32 的智能导盲拐杖项目源码分享【源码分享】
基于 STM32 的智能导盲拐杖项目,是一个非常典型的“多传感器融合 + 嵌入式控制 + 人机交互”的 IoT 辅助设备示例。它不仅具有工程价值,也有重要的社会意义。通过本文的架构讲解、模块选型和软件思路,你可以快速搭建原型,并进一步扩展成一个可投入使用的辅助产品。
基于STM32 的智能导盲拐杖项目源码分享【源码分享】
|
11月前
|
人工智能 JavaScript Linux
🚀 恢复 Cursor 缺失的功能!一键生成你的专属 AI 编程助手配置
🚀 恢复Cursor被移除的规则生成功能!`generate-cursor-rule`一键安装,AI智能分析项目,自动生成专属`.cursorrules`文件,支持全平台,零配置使用,提升开发效率,团队协作更统一。告别手动编写,让AI助手更懂你的代码风格!
573 9
|
11月前
|
JSON Dubbo Java
Feign远程调用
本章介绍如何使用Feign替代RestTemplate实现更优雅的HTTP跨服务调用。通过引入Feign,结合注册中心与注解声明,解决硬编码、可读性差等问题,并支持日志、连接池等自定义配置。同时提出继承与抽取两种最佳实践,推荐将Feign客户端抽离为独立模块,提升代码复用性与维护性,助力微服务架构优化。
347 0
Feign远程调用
|
12月前
|
运维 监控 JavaScript
Nginx报警问题排查(从零开始快速定位与解决常见报警)
本文教你如何排查Nginx常见报警,如502错误、连接超时等。通过查看错误日志、检查配置语法、验证后端服务状态及优化监控策略,快速定位并解决问题。适合运维与开发新手,助你成为排障高手。关键词:Nginx报警排查、错误日志、配置错误、服务器监控。
THW
|
11月前
|
存储 安全
BadUSB 攻击原理
BadUSB攻击通过将USB设备伪装成键盘等HID设备,利用系统对HID的信任,在连接电脑后自动模拟键盘输入执行恶意指令,从而绕过传统安全防护,实现无需用户操作的秒级入侵。
THW
1325 0
|
数据采集 网络协议 API
协程+连接池:高并发Python爬虫的底层优化逻辑
协程+连接池:高并发Python爬虫的底层优化逻辑
|
机器学习/深度学习 数据采集 消息中间件
|
人工智能 缓存 运维
LangServe如何革新LLM应用部署?
【10月更文挑战第3天】
616 1