標籤:return throws lse turn reader output create set 命令
使用phantomjs對網頁進行遇到的問題問題描述:
- 使用的phantomjs版本:phantomjs-2.1.1-windows
- 使用的js檔案,\phantomjs-2.1.1-windows\examples\rasterize.js
- 使用的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); });}
- 使用百度連結,拋出上面提到的異常.後台沒有圖片
- 使用cnblogs連結,拋出上面的異常,後台有圖片
問題分析
不懂,不知道,去他媽的
問題解決
- 把代碼更改為:
while ((tmp = reader.readLine()) != null) { }close(process,reader);
可以解決拋出異常和後台無法擷取圖片的問題,但是如果使用22.js,會出現程式運行完無法自動停止的問題.
- 注意到,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; }
此時能正常運行,後台也有圖片.
- 按照第二種更改後的條件下,在把js檔案更改為:\phantomjs-2.1.1-windows\examples\rasterize.js,程式能正常運行,後台有圖片;
推薦解決辦法
代碼更改為:
while ((tmp = reader.readLine()) != null) { close(process,reader); break; }
phantomjs拋出IOException