我在使用praw,cx_freeze,pyside和请求时遇到麻烦,在冻结之前一切正常,但是当我冻结这种情况时,请求出错了我认为: http://pastie.org/10614254
这是我正在使用的项目:https://github.com/MrCappuccino/WallDit-QT
这是我的setup.py:https://gist.github.com/MrCappuccino/0f1b0571d29d47a95895
import sys
import cx_Freeze
import PySide
import praw
import requests.certs
from cx_Freeze import setup, Executable
exe = Executable(
script="WallDit_QT.py",
base="Win32GUI",
targetName="WallDit_QT.exe"
)
#includefiles = ['README.txt', 'CHANGELOG.txt', 'helpers\uncompress\unRAR.exe', , 'helpers\uncompress\unzip.exe']
#build_exe_options = {"packages": ["os"], "includefiles": ['README.txt', 'CHANGELOG.txt']}
setup(name = 'WallDit_QT',
version = '1.0',
author = 'Disco Dolan',
description ='Set your wallpaper interactively!',
executables = [exe],
options = {'build.exe': {"include_files":['cacert.pem', 'praw.ini', 'README.md']}},
requires = ['PySide', 'cx_Freeze', 'praw', 'shutil', 'requests']
)
任何人都可以帮忙吗?
我尝试添加cacert.pem,但无济于事,此时我已经没有更多想法了
答案 0 :(得分:1)
对于某些冻结的应用程序,您必须在冻结的应用程序中设置cacert(或一般的外部数据)路径。
Setup.py部分
首先需要将其包含在构建选项中并手动指定安装目录。这是setup.py中唯一的部分:
# notice how I say the folder the certificate is installed
{"include_files":[(requests.certs.where(),'cacert.pem')]}
在您的情况下,这会生成以下设置文件:
import requests
import sys
# more imports
setup(name = 'WallDit_QT',
version = '1.0',
author = 'Disco Dolan',
description ='Set your wallpaper interactively!',
executables = [exe],
options = {
'build.exe': {
"include_files": [
(requests.certs.where(),'cacert.pem'),
'praw.ini',
'README.md'
]
}
},
requires = ['PySide', 'cx_Freeze', 'praw', 'shutil', 'requests']
)
申请部分
然后,您需要在运行时在冻结的应用程序中获取证书路径。 对于PyInstaller,路径在运行时定义到名为_MEIPASS的数据目录(可以从sys._MEIPASS获取),允许您访问应用程序所需的所有数据。在cacert.pem的情况下,路径将确定如下:
cacertpath = os.path.join(sys._MEIPASS, "cacert.pem")
对于cx_Freeze,可以从安装路径确定路径并将其与所需数据连接。在这里,我们得到如下路径:
cacertpath = os.path.join(datadir, 'cacert.pem')
您可以使用以下内容轻松获取冻结应用程序的数据目录:
datadir = os.path.dirname(sys.executable)
(请注意,这不适用于非冻结应用程序,因此为了确保它适用于冻结和非冻结应用程序,Cx_Freeze recommends您可以按如下方式对其进行编码):
def find_data_file(filename):
if getattr(sys, 'frozen', False):
# The application is frozen
datadir = os.path.dirname(sys.executable)
else:
# The application is not frozen
# Change this bit to match where you store your data files:
datadir = os.path.dirname(__file__)
return os.path.join(datadir, filename)
然后,您将所有请求模块GET和POST请求包含在此路径中,如下所示:
request.get(url, headers=headers, verify=cacertpath)
示例1
示例代码段如下:
# load modules
import os
import sys
import requests
# define our path finder
def find_data_file(filename):
if getattr(sys, 'frozen', False):
# The application is frozen
datadir = os.path.dirname(sys.executable)
else:
# The application is not frozen
# Change this bit to match where you store your data files:
datadir = os.path.dirname(__file__)
return os.path.join(datadir, filename)
# get our cacert path and post our GET request
cacertpath = find_data_file('cacert.pem')
r = requests.get('https://api.github.com/events', verify=cacertpath)
# print the text from the request
print(r.text)
示例2
您还可以通过执行以下操作告诉请求将来在哪里找到证书:
os.environ["REQUESTS_CA_BUNDLE"] = cacertpath
在这种情况下,我们会执行以下操作。这里的优点是cacertpath不会在每个模块中明确定义(或从其他模块导入),并且可以在环境中定义。
import os
import sys
import requests
def find_data_file(filename):
if getattr(sys, 'frozen', False):
# The application is frozen
datadir = os.path.dirname(sys.executable)
else:
# The application is not frozen
# Change this bit to match where you store your data files:
datadir = os.path.dirname(__file__)
return os.path.join(datadir, filename)
cacertpath = find_data_file('cacert.pem')
os.environ["REQUESTS_CA_BUNDLE"] = cacertpath
r = requests.get('https://api.github.com/events')
r.text