python 请求在转换为 .exe 时找不到带有证书的文件夹
python requests can't find a folder with a certificate when converted to .exe
我有一个程序可以汇集来自不同营销系统的广告统计数据。一切正常,直到我将其转换为 .exe 格式并 运行 它。
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\user\AppData\Local\Programs\Python\Python35\lib\tkinter\__init__.py", line 1549, in __call__
return self.func(*args)
File "C:\Users\user\Desktop\alg\TSK_7. Marketing\report_gui.py", line 24, in <lambda>
ok = tk.Button(root, text="DO NOT PRESS", bg="red", command=lambda: self.run())
File "C:\Users\user\Desktop\alg\TSK_7. Marketing\report_gui.py", line 43, in run
report.merge_all()
File "C:\Users\user\Desktop\alg\TSK_7. Marketing\process_data.py", line 400, in merge_all
fb_df = self.fetch_fb()
File "C:\Users\user\Desktop\alg\TSK_7. Marketing\process_data.py", line 156, in fetch_fb
fb_campaigns = from_fb.run_fb(self.start_date, self.end_date) # in JSON format
File "C:\Users\user\Desktop\alg\TSK_7. Marketing\from_fb.py", line 110, in run_fb
return s.get_stats()
File "C:\Users\user\Desktop\alg\TSK_7. Marketing\from_fb.py", line 84, in get_stats
params=params,
File "C:\Users\user\AppData\Local\Programs\Python\Python35\lib\site-packages\facebookads\adobjects\adaccount.py", line 1551, in get_insights
return request.execute()
File "C:\Users\user\AppData\Local\Programs\Python\Python35\lib\site-packages\facebookads\api.py", line 653, in execute
cursor.load_next_page()
File "C:\Users\user\AppData\Local\Programs\Python\Python35\lib\site-packages\facebookads\api.py", line 797, in load_next_page
params=self.params,
File "C:\Users\user\AppData\Local\Programs\Python\Python35\lib\site-packages\facebookads\api.py", line 305, in call
timeout=self._session.timeout
File "C:\Users\user\AppData\Local\Programs\Python\Python35\lib\site-packages\requests\sessions.py", line 508, in request
resp = self.send(prep, **send_kwargs)
File "C:\Users\user\AppData\Local\Programs\Python\Python35\lib\site-packages\requests\sessions.py", line 618, in send
r = adapter.send(request, **kwargs)
File "C:\Users\user\AppData\Local\Programs\Python\Python35\lib\site-packages\requests\adapters.py", line 407, in send
self.cert_verify(conn, request.url, verify, cert)
File "C:\Users\user\AppData\Local\Programs\Python\Python35\lib\site-packages\requests\adapters.py", line 226, in cert_verify
"invalid path: {0}".format(cert_loc))
OSError: Could not find a suitable TLS CA certificate bundle, invalid path: C:\Users\user\AppData\Local\Temp\_MEI253762\facebookads\fb_ca_chain_bundle.crt
我试图通过使用此代码来修复该问题,但每次我 运行 此代码时 MEI 文件夹都会不断更改其数字,因此它没有用。
dst = r'C:\Users\user\AppData\Local\Temp\_MEI120642\facebookads'
file = 'fb_ca_chain_bundle.crt'
try:
os.makedirs(dst); ## it creates the destination folder
except:
pass
shutil.move(file, dst)
所以我去了这个文件
C:\Users\user\AppData\Local\Programs\Python\Python35\Lib\site-packages\requests\adapters.py
并尝试评论引发此错误但出现 SSL 错误的语句。我找不到一段负责生成这些 MEI 数字的代码。
def cert_verify(self, conn, url, verify, cert):
"""Verify a SSL certificate. This method should not be called from user
code, and is only exposed for use when subclassing the
:class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
:param conn: The urllib3 connection object associated with the cert.
:param url: The requested URL.
:param verify: Either a boolean, in which case it controls whether we verify
the server's TLS certificate, or a string, in which case it must be a path
to a CA bundle to use
:param cert: The SSL certificate to verify.
"""
if url.lower().startswith('https') and verify:
cert_loc = None
# Allow self-specified cert location.
if verify is not True:
cert_loc = verify
if not cert_loc:
cert_loc = DEFAULT_CA_BUNDLE_PATH
if not cert_loc or not os.path.exists(cert_loc):
raise IOError("Could not find a suitable TLS CA certificate bundle, "
"invalid path: {0}".format(cert_loc))
conn.cert_reqs = 'CERT_REQUIRED'
if not os.path.isdir(cert_loc):
conn.ca_certs = cert_loc
else:
conn.ca_cert_dir = cert_loc
else:
conn.cert_reqs = 'CERT_NONE'
conn.ca_certs = None
conn.ca_cert_dir = None
if cert:
if not isinstance(cert, basestring):
conn.cert_file = cert[0]
conn.key_file = cert[1]
else:
conn.cert_file = cert
conn.key_file = None
if conn.cert_file and not os.path.exists(conn.cert_file):
raise IOError("Could not find the TLS certificate file, "
"invalid path: {0}".format(conn.cert_file))
if conn.key_file and not os.path.exists(conn.key_file):
raise IOError("Could not find the TLS key file, "
"invalid path: {0}".format(conn.key_file))
我运行也遇到过这个问题。看起来它来自证书包 cacert.pem
,但在编译程序时未包含在 requests
包目录中。 requests
模块使用函数 certifi.core.where
来确定 cacert.pem
的位置。覆盖此函数并覆盖此函数设置的变量似乎可以解决问题。
我将这段代码添加到程序的开头:
import sys, os
def override_where():
""" overrides certifi.core.where to return actual location of cacert.pem"""
# change this to match the location of cacert.pem
return os.path.abspath("cacert.pem")
# is the program compiled?
if hasattr(sys, "frozen"):
import certifi.core
os.environ["REQUESTS_CA_BUNDLE"] = override_where()
certifi.core.where = override_where
# delay importing until after where() has been replaced
import requests.utils
import requests.adapters
# replace these variables in case these modules were
# imported before we replaced certifi.core.where
requests.utils.DEFAULT_CA_BUNDLE_PATH = override_where()
requests.adapters.DEFAULT_CA_BUNDLE_PATH = override_where()
这可能是 requests
包的问题。
我通过手动将 cacert.pem
文件从 /lib/site-packages/certifi
复制到 /lib/site-packages/requests
解决了这个问题
如果您想用 .exe
解决此问题,请将 cacert.pem
文件从 /lib/site-packages/certifi
复制到 dist/library.zip/certifi/
。
我认为您已经使用 py2exe
创建了 exe
,其中 py2exe
将在包含所有脚本依赖项的 dist/
下创建 library.zip
。我不知道其他 exe
转换器是否创建 library.zip
.
如果要禁用证书验证,可以使用requests.get()
中的verify=False
参数:
requests.get('https://example.com', verify=False)
我在使用 PyInstaller
转换为 .exe
时遇到了与 requests
包相同的问题。我正在使用 conda 的虚拟环境进行开发。我转向使用 Python's virtual environment (因为我的同事已经这样做并且没有得到同样的错误),像往常一样安装我的包,用 PyInstaller
创建了 .exe
并且没有遇到同样的错误。
我不确定 cacert.pem
文件是否正确打包到 Python 虚拟环境的 .exe
中,但在某种程度上被 conda 虚拟环境忽略了。也许其他人可以澄清为什么会这样,但我希望这对您有所帮助!
我通过输入以下代码解决了它:
import os
import sys
import certifi
os.environ['REQUESTS_CA_BUNDLE'] =
os.path.join(os.path.dirname(sys.argv[0]), certifi.where())
通过这个我检测到“cacert.pem”的当前路径并将其放在 environ
我有一个程序可以汇集来自不同营销系统的广告统计数据。一切正常,直到我将其转换为 .exe 格式并 运行 它。
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\user\AppData\Local\Programs\Python\Python35\lib\tkinter\__init__.py", line 1549, in __call__
return self.func(*args)
File "C:\Users\user\Desktop\alg\TSK_7. Marketing\report_gui.py", line 24, in <lambda>
ok = tk.Button(root, text="DO NOT PRESS", bg="red", command=lambda: self.run())
File "C:\Users\user\Desktop\alg\TSK_7. Marketing\report_gui.py", line 43, in run
report.merge_all()
File "C:\Users\user\Desktop\alg\TSK_7. Marketing\process_data.py", line 400, in merge_all
fb_df = self.fetch_fb()
File "C:\Users\user\Desktop\alg\TSK_7. Marketing\process_data.py", line 156, in fetch_fb
fb_campaigns = from_fb.run_fb(self.start_date, self.end_date) # in JSON format
File "C:\Users\user\Desktop\alg\TSK_7. Marketing\from_fb.py", line 110, in run_fb
return s.get_stats()
File "C:\Users\user\Desktop\alg\TSK_7. Marketing\from_fb.py", line 84, in get_stats
params=params,
File "C:\Users\user\AppData\Local\Programs\Python\Python35\lib\site-packages\facebookads\adobjects\adaccount.py", line 1551, in get_insights
return request.execute()
File "C:\Users\user\AppData\Local\Programs\Python\Python35\lib\site-packages\facebookads\api.py", line 653, in execute
cursor.load_next_page()
File "C:\Users\user\AppData\Local\Programs\Python\Python35\lib\site-packages\facebookads\api.py", line 797, in load_next_page
params=self.params,
File "C:\Users\user\AppData\Local\Programs\Python\Python35\lib\site-packages\facebookads\api.py", line 305, in call
timeout=self._session.timeout
File "C:\Users\user\AppData\Local\Programs\Python\Python35\lib\site-packages\requests\sessions.py", line 508, in request
resp = self.send(prep, **send_kwargs)
File "C:\Users\user\AppData\Local\Programs\Python\Python35\lib\site-packages\requests\sessions.py", line 618, in send
r = adapter.send(request, **kwargs)
File "C:\Users\user\AppData\Local\Programs\Python\Python35\lib\site-packages\requests\adapters.py", line 407, in send
self.cert_verify(conn, request.url, verify, cert)
File "C:\Users\user\AppData\Local\Programs\Python\Python35\lib\site-packages\requests\adapters.py", line 226, in cert_verify
"invalid path: {0}".format(cert_loc))
OSError: Could not find a suitable TLS CA certificate bundle, invalid path: C:\Users\user\AppData\Local\Temp\_MEI253762\facebookads\fb_ca_chain_bundle.crt
我试图通过使用此代码来修复该问题,但每次我 运行 此代码时 MEI 文件夹都会不断更改其数字,因此它没有用。
dst = r'C:\Users\user\AppData\Local\Temp\_MEI120642\facebookads'
file = 'fb_ca_chain_bundle.crt'
try:
os.makedirs(dst); ## it creates the destination folder
except:
pass
shutil.move(file, dst)
所以我去了这个文件
C:\Users\user\AppData\Local\Programs\Python\Python35\Lib\site-packages\requests\adapters.py
并尝试评论引发此错误但出现 SSL 错误的语句。我找不到一段负责生成这些 MEI 数字的代码。
def cert_verify(self, conn, url, verify, cert):
"""Verify a SSL certificate. This method should not be called from user
code, and is only exposed for use when subclassing the
:class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
:param conn: The urllib3 connection object associated with the cert.
:param url: The requested URL.
:param verify: Either a boolean, in which case it controls whether we verify
the server's TLS certificate, or a string, in which case it must be a path
to a CA bundle to use
:param cert: The SSL certificate to verify.
"""
if url.lower().startswith('https') and verify:
cert_loc = None
# Allow self-specified cert location.
if verify is not True:
cert_loc = verify
if not cert_loc:
cert_loc = DEFAULT_CA_BUNDLE_PATH
if not cert_loc or not os.path.exists(cert_loc):
raise IOError("Could not find a suitable TLS CA certificate bundle, "
"invalid path: {0}".format(cert_loc))
conn.cert_reqs = 'CERT_REQUIRED'
if not os.path.isdir(cert_loc):
conn.ca_certs = cert_loc
else:
conn.ca_cert_dir = cert_loc
else:
conn.cert_reqs = 'CERT_NONE'
conn.ca_certs = None
conn.ca_cert_dir = None
if cert:
if not isinstance(cert, basestring):
conn.cert_file = cert[0]
conn.key_file = cert[1]
else:
conn.cert_file = cert
conn.key_file = None
if conn.cert_file and not os.path.exists(conn.cert_file):
raise IOError("Could not find the TLS certificate file, "
"invalid path: {0}".format(conn.cert_file))
if conn.key_file and not os.path.exists(conn.key_file):
raise IOError("Could not find the TLS key file, "
"invalid path: {0}".format(conn.key_file))
我运行也遇到过这个问题。看起来它来自证书包 cacert.pem
,但在编译程序时未包含在 requests
包目录中。 requests
模块使用函数 certifi.core.where
来确定 cacert.pem
的位置。覆盖此函数并覆盖此函数设置的变量似乎可以解决问题。
我将这段代码添加到程序的开头:
import sys, os
def override_where():
""" overrides certifi.core.where to return actual location of cacert.pem"""
# change this to match the location of cacert.pem
return os.path.abspath("cacert.pem")
# is the program compiled?
if hasattr(sys, "frozen"):
import certifi.core
os.environ["REQUESTS_CA_BUNDLE"] = override_where()
certifi.core.where = override_where
# delay importing until after where() has been replaced
import requests.utils
import requests.adapters
# replace these variables in case these modules were
# imported before we replaced certifi.core.where
requests.utils.DEFAULT_CA_BUNDLE_PATH = override_where()
requests.adapters.DEFAULT_CA_BUNDLE_PATH = override_where()
这可能是 requests
包的问题。
我通过手动将 cacert.pem
文件从 /lib/site-packages/certifi
复制到 /lib/site-packages/requests
如果您想用 .exe
解决此问题,请将 cacert.pem
文件从 /lib/site-packages/certifi
复制到 dist/library.zip/certifi/
。
我认为您已经使用 py2exe
创建了 exe
,其中 py2exe
将在包含所有脚本依赖项的 dist/
下创建 library.zip
。我不知道其他 exe
转换器是否创建 library.zip
.
如果要禁用证书验证,可以使用requests.get()
中的verify=False
参数:
requests.get('https://example.com', verify=False)
我在使用 PyInstaller
转换为 .exe
时遇到了与 requests
包相同的问题。我正在使用 conda 的虚拟环境进行开发。我转向使用 Python's virtual environment (因为我的同事已经这样做并且没有得到同样的错误),像往常一样安装我的包,用 PyInstaller
创建了 .exe
并且没有遇到同样的错误。
我不确定 cacert.pem
文件是否正确打包到 Python 虚拟环境的 .exe
中,但在某种程度上被 conda 虚拟环境忽略了。也许其他人可以澄清为什么会这样,但我希望这对您有所帮助!
我通过输入以下代码解决了它:
import os
import sys
import certifi
os.environ['REQUESTS_CA_BUNDLE'] =
os.path.join(os.path.dirname(sys.argv[0]), certifi.where())
通过这个我检测到“cacert.pem”的当前路径并将其放在 environ