Java&&Python混合编程

  • 一、背景
  • 二、Pyhton业务
  • 三、Java业务

一、背景

前些日子我手上接到一个需求,老板要求将一个非常复杂的网页(各种表格,各种统计图,各种数据)以图片的形式分享出去,第一时间我就觉得这个需求很奇葩,为什么不直接分享网页地址呢是吧?但是老板既然要这么一个功能我们想尽办法也得给他实现,于是我整理出了三个方案:①小程序端用canvas绘制页面并保存;②后端用Java swing绘制页面并生成图片,③小程序端访问后端,后端请求H5页面并截图,由于网页实在太复杂最终选择了方案三,后台访问截图用Python实现。

二、Pyhton业务

# -*- coding: utf-8 -*-
import sys
import time
import oss2
import json
import argparse
import base64
from selenium import webdriver
from selenium.webdriver.chrome.options import Optionsclass Result(object):def __init__(self,resutlCode,data):# 返回结果对象self.resutlCode = resutlCodeself.data = datadef to_json(self):return json.dumps(self.__dict__)def get_image(url, pic_name):print("python版本号:" + sys.version)chrome_options = Options()chrome_options.add_argument('--headless')chrome_options.add_argument('--disable-gpu')# 创建浏览器对象# windowsdriver = webdriver.Chrome(executable_path = 'E:/projects/onegolf/onegolf-parent/onegolf-server/onegolf-api/onegolf-python/windows/chromedriver', options=chrome_options)# linux# driver = webdriver.Chrome(/home/chromedriver', options=chrome_options)# 打开网页driver.get(url)# driver.maximize_window()# 加延时 防止未加载完就截图time.sleep(1)# 用js获取页面的宽高,如果有其他需要用js的部分也可以用这个方法width = driver.execute_script("return document.documentElement.scrollWidth")height = driver.execute_script("return document.documentElement.scrollHeight")# 将浏览器的宽高设置成刚刚获取的宽高driver.set_window_size(width, height)time.sleep(1)# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('ossAccessKeyId', 'ossAccessKeySecret')# Endpoint以背景为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-beijing.aliyuncs.com', 'ossBucketName')bucket.put_object('oss/image/match/' + pic_name, driver.get_screenshot_as_png())driver.quit()return Result( "200",'https://ip/oss/image/match/' + pic_name)def base64_str_decode(base64_str):temp = bytes(base64_str, encoding='utf-8')return bytes(base64.b64decode(temp)).decode()if __name__ == "__main__":# 读取入参网页地址+图片名称parser = argparse.ArgumentParser()parser.add_argument('-params')args = parser.parse_args()# base64解码param = base64_str_decode(args.params)print("请求参数:" + param)task = json.loads(param)url = task[0]pic_name = task[1]print("url:" + url + ",pic_name:" + pic_name)# 返回结果result = Nonetry:result = get_image(url, pic_name)except Exception as e:print(e)# 输出结果,由Java接收sys.stdout = sys.__stdout__print("<<<<out<<<<")print(result.to_json())print(">>>>out>>>>")

三、Java业务

package com.onegolf.base.util;import com.alibaba.fastjson.JSONObject;
import com.onegolf.common.exceptions.CommonException;
import com.onegolf.common.response.ResponseResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.system.ApplicationHome;
import org.springframework.util.Base64Utils;
import org.springframework.util.CollectionUtils;import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Collections;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;/*** python脚本处理方法*/
@Slf4j
public class PythonUtil {/*** 正则命名捕获的分组名*/private static final String RESULT = "result";private static final String OPEN_TAG = "<<<<out<<<<";private static final String CLOSE_TAG = ">>>>out>>>>";/*** python输出内容正则表达式*/private static final Pattern PATTERN = Pattern.compile(String.format("(?<result>%s.*?%s)", OPEN_TAG, CLOSE_TAG));/*** <<<<out<<<<  和  >>>>out>>>> 自身的长度*/private static final int FLAG_LENGTH = 11;private static String pythonScriptPath;// 这里回去python脚本的相对路径static {ApplicationHome applicationHome = new ApplicationHome(Object.class);// windowspythonScriptPath = applicationHome.getDir().getParentFile().getAbsolutePath()+ File.separator + "onegolf-parent" + File.separator + "onegolf-server" + File.separator + "onegolf-api" + File.separator + "onegolf-python";// linux// pythonScriptPath = "/home";}/*** 调用python获取截图地址** @return 执行结果状态*/public static ResponseResult callAiTrainTask(List<String> cellNames) {if (CollectionUtils.isEmpty(cellNames)) {cellNames = Collections.emptyList();}try {log.info("Starting execution");// 这里的result对象和python的返回对象要一致ResponseResult result =callFunction("process.py", cellNames, ResponseResult.class);log.info("Execution finished");return result;} catch (CommonException e) {log.error("Execution fail with error", e);ResponseResult result = new ResponseResult();result.setResultCode("500");result.setResultDesc(e.getMessage());return result;}}/** *这里将python返回结果对象反序列换成java需要返回的对象*/private static <P, R> R callFunction(String fileName, P params, Class<R> returnType)throws CommonException {String paramsJson = JSONObject.toJSONString(params);paramsJson = Base64Utils.encodeToString(paramsJson.getBytes());String resultJson = callFunction(pythonScriptPath + File.separator + fileName, paramsJson);try {return JSONObject.parseObject(resultJson, returnType);} catch (Exception e) {log.error("返回结果反序列化失败:" + resultJson);return null;}}/** *调用python的核心实现*/private static String callFunction(String fullFileName, String params) throws CommonException {String command = String.format("python %s -params %s", fullFileName, params);log.info("execute python command->" + command);try {Process process = Runtime.getRuntime().exec(command);BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));BufferedReader errReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));String temp;String errorInfo;while ((errorInfo = errReader.readLine()) != null){log.debug(errorInfo);}StringBuilder resultBuilder = new StringBuilder();boolean openTagFound = false;while ((temp = reader.readLine()) != null) {if (!openTagFound) {// 找到OPEN_TAG标志前丢弃python输出,否则消息很长if (!temp.contains(OPEN_TAG)) {continue;} else {openTagFound = true;}}resultBuilder.append(temp);}String result = resultBuilder.toString();Matcher matcher = PATTERN.matcher(result);if (matcher.find()) {result = matcher.group(RESULT);result = result.substring(FLAG_LENGTH, result.length() - FLAG_LENGTH);return result;}return "";} catch (IOException e) {log.error("find a python function error", e);throw new CommonException(e.getMessage());}}
}

Python(二)JavaPython混合编程相关推荐

  1. c python boost.python_如何利用Boost.Python实现Python C/C++混合编程详解

    前言 学习中如果碰到问题,参考官网例子:D:boost_1_61_0libspythontest 参考:Boost.Python 中英文文档. 利用Boost.Python实现Python C/C++ ...

  2. 杠子老虎鸡虫 《python二维游戏编程》课后项目一

    <python二维游戏编程>项目一:杠子老虎鸡虫 V0.0.2.20210629 项目简介 <python二维游戏编程>课后项目1 适用于中国农业出版社,张太红主编,2015版 ...

  3. 【原】使用Json作为Python和C#混合编程时对象转换的中间文件

    一.Python中自定义类对象json字符串化的步骤[1] 1. 用 json 或者simplejson 就可以: 2.定义转换函数: 3. 定义类 4. 生成对象 5.dumps执行,引入转换函数 ...

  4. 基于Python和Java混合编程实现的小学生数学口算题卡定制练习题

    1. 总体要求 综合运用软件工程的思想,协同完成一个软件项目的开发,掌软件工程相关的技术和方法: 组成小组进行选题,通过调研完成项目的需求分析,并详细说明小组成员的分工.项目的时间管理等方面. 根据需 ...

  5. python和c混合编程 gil_终于搞明白python与gil

    感想:东看一篇文章西看一篇文章,终于把gil的概念理顺了 我们都知道,比方我有一个4核的CPU,那么这样一来,在单位时间内每个核只能跑一个线程,然后时间片轮转切换.但是Python不一样,它不管你有几 ...

  6. python与c混合编程 版本_python与C、C++混编的四种方式(小结)

    混编的含义有两种, 一种是在python里面写C 一种是C里面写python 本文主要是进行简化,方便使用. ############################################# ...

  7. python与matlab混合编程_python 与 matlab 混编

    Matlab的官方文档中介绍了 Matlab 与其余编程语言之间的引擎接口,其中包括对于 Python 开放的引擎 API,可参考官方教程,其中包括引擎安装,基本使用,以及Python与Matlab之 ...

  8. Boost.Python实现Python C/C++混合编程

    导出函数 #include<string> #include<boost/python.hpp>using namespace std; using namespace boo ...

  9. python和c混合编程 gil,如何在python中使用C扩展来解决GIL

    I want to run a cpu intensive program in Python across multiple cores and am trying to figure out ho ...

  10. cuda编程python接口_混合编程[python+cpp+cuda]

    很多时候,我们是基于python进行模型的设计和运行,可是基于python本身的速度问题,使得原生态python代码无法满足生产需求,不过我们可以借助其他编程语言来缓解python开发的性能瓶颈.这里 ...

最新文章

  1. 2018 年值得关注的 Web 设计趋势
  2. oracle 11g 大量废连接占满数据库连接问题处理
  3. 【AI初识境】被Hinton,DeepMind和斯坦福嫌弃的池化,到底是什么?​​​​​​​
  4. c# gerber文件读取_懒猪编程实例六:Visual C# 实现外部文件的读取和写入
  5. java list适配器_详解listview的四种适配器模式
  6. HID报表描述符(目前最全的解析,也是USB最复杂的描述符)
  7. CodeForces - 1537E2 Erase and Extend (Hard Version)(扩展KMP-比较两个前缀无限循环后的字典序大小)
  8. 【2018.5.19】模拟赛之一-ssl2432 面积最大【数学】
  9. 如何用c语言倒序输出字母,菜鸟求助-如何用指针法将一串字符按单词的倒序输出?如:i love yo...
  10. 华为新系统鸿蒙能互通吗,「连接」万物的鸿蒙,能拯救华为手机吗?
  11. BS 百度Blog的字节限制!!!!!!!!!
  12. centos安装rpm格式jdk
  13. 在windows的IDE中使用linux命令行
  14. 关系抽取综述及相关顶会论文介绍
  15. matlab绝对均值,MATLAB中均值、方差、均方差的计算方法
  16. 2018年 第九届 蓝桥杯省赛 C/C++ B 组
  17. 龙卷风路径_龙卷风的目录
  18. 计算机共享的媒体设备,多台计算机、手机和平板电脑中共享对文件和媒体的访问时怎么做...
  19. 使用 ifconfig 查看本机 ip
  20. 《Love and Math》(1)

热门文章

  1. c语言图书管理系统登录系统,C语言图书管理系统设计代码.doc
  2. python的localtime函数_python的内置函数time
  3. MATLAB 2018a 安装
  4. 大事件,Java被超越了,2021年5月TIOBE编程语言排行榜出炉
  5. CTF_BUGKU_WEB_game1
  6. python怎么画散点图_用python画xy散点图
  7. 教程贴--DISM 安装系统
  8. 单片机作业1_为OLED制作汉字字库_第1部分
  9. 一到九乘法口诀VB源码
  10. java图书管理系统源码免费_Java图书管理系统 附源码