修复用py2exe(或PyInstaller)编译的exe中的SSL证书错误

时间:2013-06-17 23:37:00

标签: python ssl py2exe python-requests pyinstaller

我刚刚完成了一个Python程序测试,该程序涉及登录网站并需要设置CSRF cookie。我尝试使用py2exe将其打包为exe并出现套接字错误。当我尝试使用PyInstaller时遇到同样的问题。谷歌搜索Errno我发现其他一些人有同样的问题,因此我知道问题与SLL证书的位置有关。

这是我的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)

错误出现在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

这是否意味着问题出在requests.adapters

如果是这样,我可以在已安装的Python软件包中编辑它以在其他地方查找cacert.pem,使用py2exePyInstaller重建我的exe,然后在我安装的版本中更改它蟒?

修改

我现在在使用PyInstaller进行编译并在所有verify=Falserequests.get()调用中设置requests.post()后运行该程序。但SSL有一个原因,我真的希望能够在让任何人使用该工具之前修复此错误。

4 个答案:

答案 0 :(得分:4)

如果使用pyinstaller ...在hook-requests.py中为包含

的请求lib创建一个PyInstaller\hooks\文件
from hookutils import collect_data_files

# Get the cacert.pem
datas = collect_data_files('requests') 

答案 1 :(得分:3)

除了frmdstryr给出的答案外,我还必须告诉requests cacert.pem所在的位置。我在导入后立即添加了以下行:

# 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')

此解决方案源自此链接:http://kittyandbear.net/python/pyinstaller-request-sslerror-manual-cacert-solution.txt

答案 2 :(得分:3)

如果您正在使用&#34;请求&#34;这可以轻松解决。模块。

1)将以下代码放在主python文件中,其中&#34;请求&#34;使用模块

os.environ['REQUESTS_CA_BUNDLE'] = "certifi/cacert.pem"

2)在存在exe的可分发文件夹中,创建一个名为&#34; certifi&#34;的文件夹。并放置&#34; cacert.pem&#34;在其中的文件。

3)你可以找到&#34; cacert.pem&#34;文件

pip install certifi

import certifi
certifi.where()

太棒了..现在你的distributable包含了验证ssl调用的必要证书。

答案 3 :(得分:0)

我也在为此苦苦挣扎,hook-requests.py 提供的 frmdstryr 对我不起作用。但是这个修改过的:

from PyInstaller.utils.hooks import collect_data_files

# Get the cacert.pem
datas = collect_data_files('certifi')