python zxing库执行失败的问题(Unexpected subprocess return code 1', 'java', None)

最近写爬网课的脚本,其中有个功能需要使用二维码图片的识别,于是乎使用了zxing库来实现这个功能,主要代码如下:

import zxing
reader = zxing.BarCodeReader()  # 创建BarCodeReader对象
barcode = reader.decode(imagePath)  # 识别二维码中的信息
scene = urllib.parse.parse_qs(urllib.parse.urlparse(barcode.parsed).query)['scene'][0]  # 提取url中的scene参数

之后在Pycharm上进行了调试,调试过程中也顺利,zxing库可以正常识别出二维码图片中的URL。
为了方便朋友也能使用到该脚本,我使用了pyinstaller命令对脚本进行了打包,并开源。希望可以帮助到其他人。不久后,就有朋友反馈程序中个别功能异常。异常提示如下:
(Unexpected subprocess return code 1', 'java', None)

异常提示

根据脚本的功能分析,应该是Zxing库使用出的问题。结合提示,初步猜测很可能是Zxing库里使用了subprocess去启动一些外部程序,但出了问题(java,很可能调用jar包出错)。

于是乎,网上搜索了一下该异常的解决方案,但是在网上并没有找到相关处理方案。不过倒是证实了一个问题,zxing库识别图片二维码的方式,就是通过调用jar包来实现的。


接下来,我将报错的提示拿到源码里面进行直接搜索

源码分析

如上图,通过异常提示出现的位置,逐步往上回溯代码,大致明白了Zxing库的工作原理,zxing应该是通过cmd命令来启动的jar包,通过调用jar包来识别图片二维码。而我们的异常信息里,应该是没找到jar包,即cmd命令里面的路径参数有问题。再结合Debug功能对变量进行追踪和分析,得出结论是self.classpath这个变量出的问题,于是乎再往上追溯到我们一开始创建BarCodeReader对象的代码那,zxing.BarCodeReader()

BarCodeReader对象的实例化

从源码可以看出来,我们初始化对象时,由于没有传入classspath参数(jar所在目录),因此程序通过以下2个方式判断获取该目录路径:

  1. 首先,程序默认先在电脑的环境变量里面找该路径(ZXING_CLASSPATH,是zxing的jar包所在路径,由于我们是通过pip命令添加该zxing库的,因此电脑的环境变量没有这路径)。
  2. 其次,则从当前源码代码的相对位置找,其实就是直接从我们pip出来的第三方库里面找。

总而言之,现在就是程序代码打包后,程序没打包到这jar包,程序也没能找到这jar包。我们只需要将jar一起打包进去,并设置好这classpath路径即可。

解决方案1:添加将zxing库的jar包路径添加到全局变量中

如下图,全局变量的变量名为ZXING_CLASSPATH,变量值则为jar包的路径(自己到第三方库找路径,记得路径后面要加 *号),如图

添加全局变量

补充:这方案治标不治本,不建议采用。程序在其他人电脑运行后,依旧会有这个问题,因为人家电脑没有Zxing库的环境,照样找不到jar包路径。

解决方案2:将jar包一起打包进程序里。

1、将zxing库用到的jar包目录添加到pyinstaller打包的配置路径里的datas参数里(这个spec文件在使用pyinstaller对程序进行打包时会自动生成。如果项目里还没有这文件的话,就先将程序打包一次,等着文件出现了再进行修改,打包第二次)

image.png

2、修改代码,创建BarCodeReader对象时设置好的jar路径参数

import zxing
reader = zxing.BarCodeReader(classpath='java/*')  # 创建BarCodeReader对象
barcode = reader.decode(imagePath)  # 识别二维码中的信息
scene = urllib.parse.parse_qs(urllib.parse.urlparse(barcode.parsed).query)['scene'][0]  # 提取url中的scene参数

3、重新打包程序
pyinstaller 2号培训课程学习脚本.spec
2号培训课程学习脚本.spec就是我们前面修改的配置文件了,程序打包后会生成一个程序目录,这回里面就包含有jar包目录了,也能够正常使用。美中不足的是,程序没办法打包成单个exe文件,不过好在程序能够正常使用。

打包后的程序,里面就有jar包了

补充:由于我们在代码里面修改了jar包的默认路径(classpath),即定义了jar包的位置当前程序的java目录下,因此,代码在IDEA上开发和调试时,就会又找不到jar包了。因此,为了方便我们开发调试,我们可以将jar包目录复制到我们程序的目录下,如下图


第三方库Zxing库
image.png

参考链接:
Python zxing 库解析(条形码二维码识别)
pyinstaller打包exe,调用第三方库

你可能感兴趣的:(python zxing库执行失败的问题(Unexpected subprocess return code 1', 'java', None))