我刚刚完成了一个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,使用py2exe
或PyInstaller
重建我的exe,然后在我安装的版本中更改它蟒?
修改
我现在在使用PyInstaller
进行编译并在所有verify=False
和requests.get()
调用中设置requests.post()
后运行该程序。但SSL有一个原因,我真的希望能够在让任何人使用该工具之前修复此错误。
答案 0 :(得分:4)
如果使用pyinstaller ...在hook-requests.py
中为包含
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')