java調用python指令碼

來源:互聯網
上載者:User

標籤:roc   utf-8   while   net   proc   from   rac   charm   code   

這篇部落格旨在吐血分享今天遇到的java調用python指令碼遇到的坑,折騰了3個多小時終於可以跑通了,代碼超級短,但網上的好多資料都是抄來抄去的,很少有能夠直接跑通的,尤其是針對你的python檔案中用到第三方類庫的情況。

先來說說我為什麼要用java調用python代碼,原因就在於python在爬蟲方面提供了豐富的類庫,但我本來已經有一套java操作資料庫以及訊息中介軟體的代碼,這些代碼用python實現的話可能需要至少一周時間,為了減少時間成本,因此我決定用java調用python指令碼的方式使用requests等等庫,下面把我解決的過程分享出來,希望能給遇到類似問題的朋友一點協助。

常見的java調用python指令碼方式
  • 通過jython.jar提供的類庫實現
  • 通過Runtime.getRuntime()開啟進程來執行指令檔
通過jython.jar提供的類庫實現

通過jython.jar實現的話,我們需要引入jar包,具體我寫了一個demo,假設你的python代碼為test.py:

def my_test(name, age):    print("name: "+name)    print("age: "+age)    return "success"

java調用test.py代碼:

public static void main(String[] args) {      PythonInterpreter interpreter = new PythonInterpreter();        interpreter.execfile("E:\\workspace\\pycharm_workspace\\weixincrawer\\test.py");        PyFunction function = (PyFunction)interpreter.get("my_test",PyFunction.class);        PyObject pyobject = function.__call__(new PyString("huzhiwei"),new PyString("25"));       System.out.println("anwser = " + pyobject.toString());      }

輸出結果:

name: huzhiweiage: 25anwser = success

到此是沒有什麼問題的,我們使用function.call方法傳入參數調用python函數,使用pyobject.toString()方法拿到python中my_test函數的傳回值,但是如果你把test.py稍微做下修改如下:

import requestsdef my_test(name, age):    response = requests.get("http://www.baidu.com")    print("name: "+name)    print("age: "+age)    return "success"

不修改java調用代碼的情況下,你會得到下面異常資訊:

ImportError: No module named requests

沒錯,這就是我要討論的問題,因為jython不可能涵蓋所有python第三方類庫的東西,所以在我們得python檔案中用到requests類庫的時候,很顯然會報找不到模組的錯誤,這個時候我們是可以通過Runtime.getRuntime()開啟進程來執行python指令檔的。

通過Runtime.getRuntime()開啟進程來執行指令檔

使用這種方式需要同時修改python檔案以及java調用代碼,在此我同樣在上面test.py的基礎上進行修改:

import requestsimport sysdef my_test(name, age):    response = requests.get("http://www.baidu.com")    print("url:"+response.url)    print("name: "+name)    print("age: "+age)    return "success"my_test(sys.argv[1], sys.argv[2])

和上面test.py代碼最大的區別在於,我們此處開啟進程的方式實際上是在隱形的調用dos介面進行操作,因此在python代碼中我們需要通過sys.argv的方式來拿到java代碼中傳遞過來的參數。

java調用代碼部分:

public static void main(String[] args) {      String[] arguments = new String[] {"python", "E:\\workspace\\pycharm_workspace\\weixincrawer\\test.py", "huzhiwei", "25"};        try {            Process process = Runtime.getRuntime().exec(arguments);            BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));            String line = null;            while ((line = in.readLine()) != null) {                System.out.println(line);            }            in.close();            int re = process.waitFor();            System.out.println(re);        } catch (Exception e) {            e.printStackTrace();        }      }

結果輸出:

url:http://www.baidu.com/name: huzhiweiage: 250

在此需要注意的一點,java代碼中的process.waitFor()傳回值為0表示我們調用python指令碼成功,傳回值為1表示調用python指令碼失敗,這和我們通常意義上見到的0與1定義正好相反。

My Code:

#!/usr/bin/env python# -*- coding: utf-8 -*-# @Date    : 2018-02-27# @Author  : zhangmingchengfrom PIL import Imageimport imagehashimport sysdef get_hash(path):    image = Image.open(path)    h = str(imagehash.dhash(image))    print h    return h get_hash(sys.argv[1])

java

/** * 擷取影像dhash,擷取完後將影像刪除 */@Overridepublic String getDhash(String absolutePathName) {String dhash = "";String[] arguments = new String[] { "python", "/root/imagedhash/rest.py", absolutePathName };try {Process process = Runtime.getRuntime().exec(arguments);BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));String line = null;while ((line = in.readLine()) != null) {dhash = line;}in.close();process.waitFor();} catch (Exception e) {e.printStackTrace();}File file = new File(absolutePathName);if (file.exists() && file.isFile()) {file.delete();System.out.println(absolutePathName + "影像的dhash值=" + dhash + ",刪除影像成功");}return dhash;}

轉自:http://blog.csdn.net/hzw19920329/article/details/77509497

(轉)java調用python指令碼

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.