[英]Fixing SSL certificate error in exe compiled with py2exe (or PyInstaller)
I've just finished testing a Python programme which involves logging into a site and requires a CSRF cookie to be set.我刚刚完成了一个 Python 程序的测试,该程序涉及登录站点并需要设置 CSRF cookie。 I've tried packaging it as an exe using
py2exe
and got a socket error.我尝试使用
py2exe
其打包为 exe 并出现套接字错误。 I have the same problem when I try with PyInstaller
.当我尝试使用
PyInstaller
时,我PyInstaller
了同样的问题。 Googling the Errno I found a few other people with the same problem and so I know the problem is to do with the location of SLL certificates.谷歌搜索 Errno 我发现其他一些人也有同样的问题,所以我知道问题与 SLL 证书的位置有关。
This is my site_agent
class including the logging calls.这是我的
site_agent
类,包括日志记录调用。
class site_agent:
self.get_params()
URL = root_url + '/accounts/login/'
# Retrieve the CSRF token first
self.agent = requests.session()
self.agent.get(URL) # retrieves the cookie # This line throws the error
self.csrftoken = self.agent.cookies['csrftoken']
# Set up login data including the CSRF cookie
login_data = {'username': self.username,
'password': self.password,
'csrfmiddlewaretoken' : self.csrftoken}
# Log in
logging.info('Logging in')
response = self.agent.post(URL, data=login_data, headers=hdr)
The error comes at the self.agent.get(URL)
line and the Traceback shows:错误出现在
self.agent.get(URL)
行和 Traceback 显示:
Traceback (most recent call last):
File "<string>", line 223, in <module>
File "<string>", line 198, in main
File "<string>", line 49, in __init__
File "C:\pyinstaller-2.0\pyinstaller-2.0\autoresponder\b
uild\pyi.win32\autoresponder\out00-PYZ.pyz\requests.sessions", line 350, in get
File "C:\pyinstaller-2.0\pyinstaller-2.0\autoresponder\b
uild\pyi.win32\autoresponder\out00-PYZ.pyz\requests.sessions", line 338, in requ
est
File "C:\pyinstaller-2.0\pyinstaller-2.0\autoresponder\b
uild\pyi.win32\autoresponder\out00-PYZ.pyz\requests.sessions", line 441, in send
File "C:\pyinstaller-2.0\pyinstaller-2.0\autoresponder\b
uild\pyi.win32\autoresponder\out00-PYZ.pyz\requests.adapters", line 331, in send
requests.exceptions.SSLError: [Errno 185090050] _ssl.c:336: error:0B084002:x509
certificate routines:X509_load_cert_crl_file:system lib
Does this mean that the problem is in requests.adapters
?这是否意味着问题出在
requests.adapters
?
If so, can I just edit it in my installed Python packages to look for cacert.pem somewhere else, rebuild my exe with py2exe
or PyInstaller
, then change it back in my installed version of Python?如果是这样,我是否可以在我安装的 Python 包中编辑它以在其他地方查找 cacert.pem,使用
py2exe
或PyInstaller
重建我的 exe,然后在我安装的 Python 版本PyInstaller
其改回?
EDIT编辑
I now have the programme running after compiling with PyInstaller
and setting verify=False
in all requests.get()
and requests.post()
calls.我现在在使用
PyInstaller
编译并在所有requests.get()
和requests.post()
调用中设置verify=False
后运行程序。 But SSL is there for aa reason and I'd really like to be able to fix this error before letting anyone use the tool.但是 SSL 存在是有原因的,我真的希望能够在让任何人使用该工具之前修复此错误。
If using pyinstaller... create a hook-requests.py
file in PyInstaller\\hooks\\
for the requests lib containing如果使用 pyinstaller... 在
PyInstaller\\hooks\\
为包含的请求库创建一个hook-requests.py
文件
from hookutils import collect_data_files
# Get the cacert.pem
datas = collect_data_files('requests')
This can be solved easily if you are using "requests" module.如果您使用“请求”模块,这可以轻松解决。
1) Place the below code in your main python file where "requests" module is used 1)将以下代码放在使用“请求”模块的主python文件中
os.environ['REQUESTS_CA_BUNDLE'] = "certifi/cacert.pem"
2) Within your distributable folder where exe is present, create a folder called "certifi" and place the "cacert.pem" file within it. 2) 在 exe 所在的可分发文件夹中,创建一个名为“certifi”的文件夹,并将“cacert.pem”文件放入其中。
3) You can find the "cacert.pem" file by 3)您可以通过以下方式找到“cacert.pem”文件
pip install certifi
import certifi
certifi.where()
Awesome.. now your distributable includes the necessary certificates to validate ssl calls.太棒了.. 现在您的发行版包括验证 ssl 调用所需的证书。
In addition to the answer given by frmdstryr
, I had to tell requests
where the cacert.pem
is.除了
frmdstryr
给出的答案frmdstryr
,我还必须告诉requests
cacert.pem
在哪里。 I added the following lines right after my imports:我在导入后立即添加了以下几行:
# Get the base directory
if getattr( sys , 'frozen' , None ): # keyword 'frozen' is for setting basedir while in onefile mode in pyinstaller
basedir = sys._MEIPASS
else:
basedir = os.path.dirname( __file__ )
basedir = os.path.normpath( basedir )
# Locate the SSL certificate for requests
os.environ['REQUESTS_CA_BUNDLE'] = os.path.join(basedir , 'requests', 'cacert.pem')
This solution is derived from this link: http://kittyandbear.net/python/pyinstaller-request-sslerror-manual-cacert-solution.txt此解决方案源自此链接: http : //kittyandbear.net/python/pyinstaller-request-sslerror-manual-cacert-solution.txt
I was struggling with this as well, The hook-requests.py
provided by frmdstryr
did not work for me.我也在为此苦苦挣扎,
hook-requests.py
提供的frmdstryr
对我不起作用。 But this modified one did:但是这个修改过的做了:
from PyInstaller.utils.hooks import collect_data_files
# Get the cacert.pem
datas = collect_data_files('certifi')
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.