jmeter調用Python腳本(java調用Python程序)階段一(可實現版)


起因:本人不會Java代碼,但是想在jmeter(純Java語言)中去調用python腳本,來達到我的目的。於是開啟了一個漫長的新知識探索。過程崎嶇,在小巷子里繞了好久。均告失敗!!!!

一、開始各種百度找思路,最終大概流程就是這個樣子的(以下所有操作均在window下進行)。

  1、下載所需文件(包含JDK、Java編輯器、Python編輯器、Python3.6、jython-standalone-2.7.1.jar);

  2、安裝並配置JDK環境變量(本人所用為版本為:JDK 64位 1.8.0_211);

  3、安裝並配置Python環境(本人所用為:Python3.6、2.7版);

  4、安裝Java編輯器(本人所用為:Eclipse);

  5、安裝Python編輯器(本人所用為:PyCharm);

  6、配置jython環境變量;

  7、編寫Python測試腳本;

  8、新建Java項目;

  9、Java項目加載jython-standalone-2.7.1.jar包;

  10、編寫Java測試腳本;

  11、調試;

二、接下來就讓我們一起來踩坑、填坑吧,吼吼吼~

  1、下載所需文件,其中JDK、jython-standalone-2.7.1.jar、Eclipse、PyCharm 已提供下載地址:

  鏈接:https://pan.baidu.com/s/1TQvm0uxxYFXa_ICck86-hg
  提取碼:812d 

  2、配置JDK環境變量(自行百度解決)

  3、安裝並配置Python環境

    1)、下載Python;去官網—>   https://www.python.org/downloads/release/python-374/

    2)、安裝並配置環境;去這里—>   https://jingyan.baidu.com/article/c45ad29c05c208051653e270.html

  4、安裝Java編輯器Eclipse

    1)、將下載好的壓縮包進行解壓 (免安裝),點擊 eclipse.exe文件啟動編輯器即可;

  5、安裝Python編輯器;(自行百度解決)

  6、配置jython環境變量;

    1)、作用:Jython的主要通途就是在Java中調用Python程序;而且,還可以直接在Jython程序中引用Java。就是一座橋,連接他和它。

    2)、配置:其實是有兩個不同的文件

           jython_installer-2.5.2.jar:需要安裝和配置環境變量的,多用於使用Java的Runtime()函數調用時。

        jython-standalone-2.7.1.jar:免安裝,需要配置環境變量,通過Jython的API進行調用。能夠指定到具體的函數和方法。

      本人采用的是第二種。配置環境變量,即將 jython-standalone-2.7.1.jar 所在的目錄(D:\java_test\lib\jython-standalone-2.7.1.jar)添加到系統環境變量的CLASSPATH中。

     (沒有這一步會報錯:java.io.IOException: Cannot run program "python": CreateProcess error=2, 系統找不到指定的文件。)

  7、編寫Python測試腳本,如下:

a = [1,2,3,4,5,6,7] b = a[:] print(b)

  8、新建Java項目

    1)、新建一個項目文件夾 java_test,在文件件中新建一個lib文件夾,將jython-standalone-2.7.1.jar復制到lib文件中;

    2)、打開Eclipse,依次新建Java項目、填寫項目名稱。(Contents中選擇Create project from existing source ,位置選擇java_test文件夾),保存;

    3)、選擇項目下的src文件后右鍵新建包,填寫包名稱,保存;

    4)、選擇新建的包右鍵新建類,填寫類名稱,保存;

  9、Java項目加載jython-standalone-2.7.1.jar包

    1)、選擇新建的Java項目,右鍵后依次選擇 “構建路徑---->配置構建路徑---->L庫---->添加JAR--->找到lib文件夾中的jython-standalone-2.7.1.jar文件;

    2)、在java_test文件夾中新建一個放Python腳本的文件Script文件夾;

    此時可以看到的文件目錄結構如下:

   

 

            

 

     其中bin、src文件夾、.classpath、.project是在創建Java項目時自動創建,bin是用來存放Java項目目錄、src存放類目錄,lib文件夾是手動添加的存放需要導入的jar文件目錄,Script文件夾是手動添加的存放需要用的Python文件目錄;

  10、編寫Java測試腳本

    1)、在Java中簡單調用Python程序,不需要傳遞參數,也不需要獲取返回值,簡單版的先測試一下有沒有問題;

    Java測試代碼如下:

package java_Test; import java.io.IOException; import org.python.util.PythonInterpreter;
public class TestIng { /** * @param args * @throws IOException * @throws InterruptedException */ public static void main(String[] args) throws IOException { // 寫入jython文件的路徑 System.setProperty("python.home","D:\\java_test\\lib\\jython-standalone-2.7.1.jar"); // 寫入Python文件的路徑 String python = "D:\\java_test\\Script\\test.py"; PythonInterpreter interp = new PythonInterpreter(); interp.execfile(python); interp.cleanup(); interp.close(); } }

簡單測試了一下結果如下:

      

   結果可以正常打印出來 ,但是報了錯,console: Failed to install '': java.nio.charset.UnsupportedCharsetException: cp0.  其實這是編碼的問題 。

  解決辦法:解決辦法為在要執行的代碼上右鍵,Run As>Run Configurations,選擇第二個頁簽Arguments,在VM arguments中添加

  -Dpython.console.encoding=UTF-8

  

 

 

   在運行就不會有那個紅的報錯了 ,歐耶~~~

  2)、以上完成算是將Java與Python文件打通了 ,但是這並不能滿足我的使用要求,因為我是需要有參數傳入和輸出的。於是乎,在Java中單向調用Python程序中的方法,需要傳遞參數,並接收返回值。Python既支持面向函數式編程,也支持面向對象編程。因此,調用Python程序中的方法也分別以面向函數式編程和面向對象式編程進行說明。

  開始第二步的征程;

    修改Python文件內容(調用方法),如下:

#coding=utf-8
import math
def power(x,y): return math.pow(x,y)

對應的Java代碼如下:

package java_Test; import java.io.IOException; import org.python.core.Py; import org.python.core.PyFunction; import org.python.core.PyObject; import org.python.util.PythonInterpreter; public class TestIng { /** * @param args * @throws IOException * @throws InterruptedException */
    public static void main(String[] args) throws IOException { System.setProperty("python.home", "D:\\java_test\\lib\\jython-standalone-2.7.1.jar"); // 1. Python面向函數式編程: 在Java中調用Python函數
        String pythonFunc = "D:\\java_test\\Script\\test.py"; PythonInterpreter pi1 = new PythonInterpreter(); // 加載python程序
 pi1.execfile(pythonFunc); // 調用Python程序中的函數
        PyFunction pyf = (PyFunction) pi1.get("power", PyFunction.class); PyObject dddRes = pyf.__call__(Py.newInteger(2), Py.newInteger(3)); System.out.println(dddRes); pi1.cleanup(); pi1.close(); } }

  第一個錯誤出現了,

   

  原因:說文件的編碼不合規,有問題 ,因為這個是直接修改后綴名來改變文件格式的所以相當於是假修改 。

  解決辦法:將文件另存為,在另存為的時候選擇文件的編碼為UTF-8。就可以解決了 

  此時此刻,第二個錯出來了 。

  

 

  如果你遇到這個問題,那么恭喜你。和我同喜了,哈哈 ~~

  然后如果你去百度,貌似是解決不了的(是真的沒有相關詳細的解決辦法說明),那我就來悄悄地告訴你是為啥子吧!!!

  原因:是jython的版本問題 ,版本太高了 ,他不支持這樣讓你玩,換個低版本的,我選jython-standalone-2.5.3.jar,於是我也把它上傳雲盤了

  詳細解決辦法:

    1)、解除之前導入的jython-standalone-2.7.1.jar版本的包,解除辦法就是將導入的辦法倒序操作就行;

    2)、刪除java_test文件夾中所有的文件,按照之前創建的文件目錄接口重新文件夾結構;

    3)、將jython-standalone-2.5.3.jar文件配置系統環境變量;

    4)、重新新建Java項目;

  期間還有其他的小問題,如:

       

 

 

      原因:代碼的編寫問題,Python代碼中一個逗號是中文版的

      解決辦法:改成英文版的就OK了

   上邊貼的代碼此時也是會報錯的,如jar路徑名稱、代碼語法等。對應的修改一下就OK了 。

三、以上是完成了第一階段的調試,接下來為我自己所需來就行調試。

 Python代碼如下(Python文件名為:Original.py):

# -*- coding: utf-8 -*-
import base64 import ast import urllib.parse def addse(Original):     # 解碼
    url_org = urllib.parse.unquote(Original) # 提取 args參數
    parameter1 = urllib.parse.urlparse(url_org) parameter2 = urllib.parse.urlparse(parameter1.fragment) # base64位解碼args參數並切片截取值
    parameter3 = base64.b64decode(parameter2.query[5:]) # 將截取的byte類型的值轉化為字符串str類型的值
    # print(parameter3) 會輸出被b包圍的字典, b 表示 byte的意思,我們只要再將byte轉換回去
    # 將str類型的值轉化為字典類型
    parameter5 = ast.literal_eval(str(parameter3,'utf-8')) # 通過for循環將字典中的值取出
    for i in parameter5: return("%s = %s" %(i,parameter5[i])) if __name__ == "__main__": addse(Original)

Java代碼如下:

package test_java; import java.io.IOException; import org.python.core.Py; import org.python.core.PyFunction; import org.python.core.PyObject; import org.python.util.PythonInterpreter; public class TestIng { /** * @param args * @throws IOException * @throws InterruptedException */
    public static void main(String[] args) throws IOException { System.setProperty("python.home", "D:\\java_test\\lib\\jython-standalone-2.5.3.jar"); // 1. Python面向函數式編程: 在Java中調用Python函數
        String pythonFunc = "D:\\java_test\\Script\\Original.py"; PythonInterpreter pi1 = new PythonInterpreter(); // 加載python程序
 pi1.execfile(pythonFunc); // 調用Python程序中的函數
        PyFunction pyf = (PyFunction) pi1.get("addse", PyFunction.class); PyObject dddRes = pyf.__call__(Py.newDecimal("https://***********.com/new/#/register/h5?args=eyJ0ZW5hbnROYW1lIjoiQUEyQkwiLCJzaGFyZVBhcmFtIjoibjM0Z0MvNHVGek5pVFdGRk1UTml1SFREUWhSUzZxNVV3NmVUSlp6cThabGF6ZVdjK0p4cWNnPT0ifQ%3d%3d" )); System.out.println(dddRes); pi1.cleanup(); pi1.cleanup(); } }

修改完參數,直接運行,狂吃,喜提報錯 :

 

 原因:根據報錯內容,可以知道是Python文件中引入的第三方包沒有找到或者Python版本問題。

 

 解決辦法:直接把Python代碼用Python2.7的語法重寫。即可解決

Python2.7語法的代碼如下:

import urlparse import base64 import ast def addse(Originals): # 解碼
    url_org = urlparse.unquote(Originals) # 提取 args參數
    parameter1 = urlparse.urlparse(url_org) parameter2 = urlparse.urlparse(parameter1.fragment) # # base64位解碼args參數並切片截取值
    parameter3 = base64.b64decode(parameter2.query[5:]) parameter5 = ast.literal_eval(str(parameter3)) # # 通過for循環將字典中的值取出
    for i in parameter5: print "%s = %s" %(i,parameter5[i]) if __name__ == "__main__": Original = "https://xxxxxxxxxxx.com/new/#/register/h5?args=eyJ0ZW5hbnROYW1lIjoiQUEyQkwiLCJzaGFyZVBhcmFtIjoibjM0Z0MvNHVGek5pVFk1UTml1S11231SUzZxNVV3NmVUSlp6cThabGF6ZVdjK0p4cWNnPT0ifQ%3d%3d" addse(Original )

再次試運行,,,,幺吼,又翻車了,換了個錯繼續報:

 

原因:提示說,Original沒有被定義。

解決辦法:修改Python代碼,不要初始化相關的信息:if __name__ == "__main__":

此時在運行,,OMG又他么報錯了 

 

 事實證明此時我的程序是通了的,但是我太菜了因為各種語法規則問題導致一直報錯問題就出在 :url_org = urlparse.unquote(Originals) 這一句上;

原因:在調用Python程序時,其中的unquote這個在urlparse這個中沒有(在pycharm中同樣的這一句卻是可以正常成功的,好奇為啥通過Java去調就失敗)。看了一下在Python2.7中關於解碼的方法調用。將解碼這一句改成:url_org = urllib.unquote_plus(Originals)   在一執行,奇跡出現了 ,沃德瑪雅,終於在控制台看到了我想要的結果。

 

 

 其實還是有點小激動的。你們是不知道像我這樣太菜的人去搞這些是有多痛苦。不過解決了所有問題,看到了成功的時候還是很激動的。

這個就先這樣吧 ,吧這些代碼打成jar包,放在jmeter里,當做正常的jar包去調用就好了 ,具體的后續在更新》》》》》》》

 

 

參考文章:

https://www.cnblogs.com/nuccch/p/8435693.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM