13

我刚刚完成了一个 Python 程序的测试,该程序涉及登录一个站点并需要设置一个 CSRF cookie。我尝试将其打包为 exe 使用py2exe并收到套接字错误。当我尝试使用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,使用py2exeor重建我的 exe PyInstaller,然后在我安装的 Python 版本中将其改回?

编辑

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

4

4 回答 4

7

如果您使用“请求”模块,这可以很容易地解决。

1)将以下代码放在使用“请求”模块的主python文件中

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

2) 在存在 exe 的可分发文件夹中,创建一个名为“certifi”的文件夹并将“cacert.pem”文件放入其中。

3)您可以通过以下方式找到“cacert.pem”文件

pip install certifi

import certifi
certifi.where()

太棒了.. 现在您的可分发文件包括验证 ssl 调用所需的证书。

于 2015-12-11T15:38:12.980 回答
5

如果使用 pyinstaller...为包含以下内容的请求库创建一个hook-requests.py文件PyInstaller\hooks\

from hookutils import collect_data_files

# Get the cacert.pem
datas = collect_data_files('requests') 
于 2014-09-24T14:12:34.453 回答
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

于 2015-01-31T02:09:39.473 回答
1

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

from PyInstaller.utils.hooks import collect_data_files

# Get the cacert.pem
datas = collect_data_files('certifi')
于 2021-08-03T15:07:25.167 回答