如何解决websocket-client Python模块中的CERTIFICATE_VERIFY_FAILED错误?

问题描述 投票:1回答:3

码:

import websocket
ws = websocket.WebSocket()
ws.connect('wss://stream2.binance.com:9443/ws/!miniTicker@arr@3000ms')
record  = ws.recv()
print(record)

我试图从Binance Websocket API获取实时数据。尝试使用此示例网址获取数据时

wss://stream.binance.com:9443/ws/bnbbtc@depth

我收到此错误,表示SSL验证失败。

ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:777)

回溯:pastebin.com/RiHn025Z

我已经尝试过的:

所以我在SO How to create Python secure websocket client request?上找到了这个问题,并按照这个代码的步骤进行操作

ws = websocket.WebSocket(sslopt={"cert_reqs": ssl.CERT_NONE})
      ws.connect("wss://stream2.binance.com:9443/ws/!miniTicker@arr@3000ms")

但随后发生了名称错误:

NameError: name 'ssl' is not defined

我试图添加一个Exception(这很荒谬但仍然......)导致了SyntaxError。

其他范围

我试过使用wss://的不同websocket API,但在第一个代码本身工作得很好。

wss://ws.blockchain.info/inv
{"op":"ping"}

条件:

我在websockets.org上尝试了一个Echo测试,wss url功能齐全。

任何帮助将不胜感激。还有其他模块专门用于binance但我想拥有原始数据所以我使用这个api。

感谢您阅读我的问题。

websocket-client的GitHub URL:https://github.com/websocket-client/websocket-client

python ssl websocket client
3个回答
2
投票

似乎websocket-client发布了自己的根证书包(不好主意),并且它附带的包不包含签署了stream2.binance.com证书(oops)的CA的特定CA证书。

您可以通过将websocket-client指向更好的捆绑来解决此问题。例如,在Ubuntu上,我在/etc/ssl/certs/ca-certificates.pem上提供了一个很好的软件包。因此:

WEBSOCKET_CLIENT_CA_BUNDLE=/etc/ssl/certs/ca-certificates.pem python wsexample.py

这样做,我得到你的示例程序转储的一些数据,可能是你所追求的数据。

更好的方法是告诉websocket-client使用操作系统提供的默认根证书包。但是,我没有看到使用websocket-client执行此操作的简单方法。你可能想看看高速公路作为一个更有特色和可靠的替代方案。


2
投票

sslopt={"cert_reqs": ssl.CERT_NONE}方式是正确的。当你得到一个NameError:NameError: name 'ssl' is not defined你需要import ssl它应该工作。解决了我的SSL相关问题。


0
投票

http://pydoc.net/websocket-client/0.46.0/websocket._http/

不确定新版本的websocket-client(0.51.0的片段)发生了什么,但旧的_http.py(链接)有一个if子句,新的只依赖于环境变量。不幸的是,它没有列在我读过的任何文档中。花了很长时间进行故障排除才找到这个位,然后我找到了这个页面。看起来像websocket-client可以更好地处理这个问题。

def _ssl_socket(sock, user_sslopt, hostname):
sslopt = dict(cert_reqs=ssl.CERT_REQUIRED)
sslopt.update(user_sslopt)

certPath = os.environ.get('WEBSOCKET_CLIENT_CA_BUNDLE')
if certPath and os.path.isfile(certPath) \
        and user_sslopt.get('ca_certs', None) is None \
        and user_sslopt.get('ca_cert', None) is None:
    sslopt['ca_certs'] = certPath
elif certPath and os.path.isdir(certPath) \
        and user_sslopt.get('ca_cert_path', None) is None:
    sslopt['ca_cert_path'] = certPath
© www.soinside.com 2019 - 2024. All rights reserved.