写在前面
开发compose desktop项目爬网站时遇到验证码处理不方便需要借助python庞大的处理能力,这时需要再项目中调用python去执行获取结果,这里记录一下使用过程。
本次开发记录基于:python 3.9,compose 1.3 java17
工具:Pycharm IntelliJ IDEA
适用场景:java项目使用python,不想再单独安装python环境,直接集成进java项目
正文
记录使用验证码识别的探索
-
开发python项目
使用开源识别框架ddddocr进行验证码识别,测试下来准确度还不错 -
安装打包工具 PyInstaller 官网文档参考
-
编写打包配置 package.py如:
from PyInstaller.utils.hooks import collect_data_files from PyInstaller.utils.hooks import collect_submodules from PyInstaller.utils.hooks import copy_metadata # python3 package.py # 定义PyInstaller的打包选项 options = { "name": "main", "onefile": True, "hidden-imports": collect_submodules("ddddocr"), "datas": collect_data_files("ddddocr"), "metadata": copy_metadata("ddddocr") } # 使用options配置PyInstaller import PyInstaller.__main__ path_list = [file[0] for file in options["datas"]] prefix = '--add-data=' suffix = ':ddddocr' newlist = [] for item in path_list: newlist.append(f'{prefix}{item}{suffix}') print(newlist) metadataList = [file[0] for file in options["metadata"]] PyInstaller.__main__.run([ "main.py", "--name=%s" % options["name"], "--onedir", # "--hidden-imports=%s" % ",".join(options["hidden-imports"]), # "--add-metadata=%s" % ",".join(metadataList), "--distpath=%s" % "dist", "--workpath=%s" % "build", "--specpath=%s" % ".", ].__add__(newlist))
-
执行
python3 package.py
-
在dist目录即可获取到包含python解释器的项目,如果配置参数是–onedir就是一个目录如果是–onefile就是一个可执行文件
-
这个目录下的文件就是我们需要的等下拷贝到java项目resources目录下
如图:
7.编写java测试代码进行调用测试
import java.io.BufferedReader
import java.io.File
import java.io.InputStreamReader
fun main(args: Array<String>) {
val args1 = arrayOf(ClassLoader.getSystemClassLoader().getResource("main/main").path, data)
var result = ""
var error = ""
runCatching {
val proc = Runtime.getRuntime().exec(args1)
proc.errorStream.bufferedReader().readText().also {
error = it
}
val lines = BufferedReader(InputStreamReader(proc.inputStream)).readLines()
println(lines)
result = lines.lastOrNull() ?: ""
proc.waitFor()
//0-成功 1-调用失败 2-Python文件执行失败
println("执行结果:" + proc.exitValue())
if (proc.exitValue() == 0) {
println("result:$result")
} else {
println("error:$error")
}
}.onFailure {
println(it)
}
}
其中 ClassLoader.getSystemClassLoader().getResource("main/main").path
是获取资源目录下可执行文件的
8.调试使用即可
以上便是我的开发过程,遇到问题切记不可照搬,理解应用。