【问题标题】:How to connect to poloniex.com websocket api using a python library如何使用 python 库连接到 poloniex.com websocket api
【发布时间】:2015-08-22 08:39:41
【问题描述】:

我正在尝试连接到 wss://api.poloniex.com 并订阅ticker。我在 python 中找不到任何工作示例。我曾尝试使用高速公路/扭曲和 websocket-client 0.32.0。

这样做的目的是获取实时代码数据并将其存储在 mysql 数据库中。

到目前为止,我已尝试使用库文档中提供的示例。它们适用于 localhost 或测试服务器,但如果我更改为 wss://api.poloniex.com,我会收到一堆错误。

这是我使用 websocket-client 0.32.0 的尝试:

from websocket import create_connection
ws = create_connection("wss://api.poloniex.com")
ws.send("ticker")
result = ws.recv()
print "Received '%s'" % result
ws.close()

这是使用高速公路/扭曲:

from autobahn.twisted.websocket import WebSocketClientProtocol
from autobahn.twisted.websocket import WebSocketClientFactory


class MyClientProtocol(WebSocketClientProtocol):

    def onConnect(self, response):
        print("Server connected: {0}".format(response.peer))

    def onOpen(self):
        print("WebSocket connection open.")

        def hello():
            self.sendMessage(u"ticker".encode('utf8'))
            self.sendMessage(b"\x00\x01\x03\x04", isBinary=True)
            self.factory.reactor.callLater(1, hello)

        # start sending messages every second ..
        hello()

    def onMessage(self, payload, isBinary):
        if isBinary:
            print("Binary message received: {0} bytes".format(len(payload)))
        else:
            print("Text message received: {0}".format(payload.decode('utf8')))

    def onClose(self, wasClean, code, reason):
        print("WebSocket connection closed: {0}".format(reason))


if __name__ == '__main__':

    import sys

    from twisted.python import log
    from twisted.internet import reactor

    log.startLogging(sys.stdout)

    factory = WebSocketClientFactory("wss://api.poloniex.com", debug=False)
    factory.protocol = MyClientProtocol

    reactor.connectTCP("wss://api.poloniex.com", 9000, factory)
    reactor.run()

非常感谢一个完整但简单的示例,展示如何使用任何 python 库连接和订阅 websocket 推送 api。

【问题讨论】:

    标签: api python-3.x websocket


    【解决方案1】:

    这使用了未记录的 websocket 端点,因为 Poloniex 已取消对原始 WAMP 套接字端点的支持。

    import websocket
    import thread
    import time
    import json
    
    def on_message(ws, message):
        print(message)
    
    def on_error(ws, error):
        print(error)
    
    def on_close(ws):
        print("### closed ###")
    
    def on_open(ws):
        print("ONOPEN")
        def run(*args):
            ws.send(json.dumps({'command':'subscribe','channel':1001}))
            ws.send(json.dumps({'command':'subscribe','channel':1002}))
            ws.send(json.dumps({'command':'subscribe','channel':1003}))
            ws.send(json.dumps({'command':'subscribe','channel':'BTC_XMR'}))
            while True:
                time.sleep(1)
            ws.close()
            print("thread terminating...")
        thread.start_new_thread(run, ())
    
    
    if __name__ == "__main__":
        websocket.enableTrace(True)
        ws = websocket.WebSocketApp("wss://api2.poloniex.com/",
                                  on_message = on_message,
                                  on_error = on_error,
                                  on_close = on_close)
        ws.on_open = on_open
        ws.run_forever()
    

    渠道是:

    1001 = trollbox (you will get nothing but a heartbeat)
    1002 = ticker
    1003 = base coin 24h volume stats
    1010 = heartbeat
    'MARKET_PAIR' = market order books
    

    【讨论】:

    • 我确信@Ion Scerbatiuc 之前的回答效果很好,但我使用的是Python 2.7.x,所以这个答案对我来说是一个更好的选择。 Ion 的答案基于 Python 3.5 及更高版本。
    • @riccio777 我刚开始将此代码用于订单簿(货币对)数据。消息输出如下所示: [148,394056638,[["o",0,"0.07615527","0.34317849"]]] 148: 似乎是货币对的 ID。 394056638:序列号(我假设在显示的完整订单簿之前的最后一个序列值)“o”+0:orderBookRemove“o”+1:orderBookModify“0.07615527”:价格“0.34317849”:数量
    • 除了@GabeSpradlin 提到的你还有:["t","9394200",1,"5545.00000000","0.00009541",1508060546] 这是一个交易条目 (t),定义为 [trade, tradeId, 0/1 (sell/buy), price, amount, timestamp]
    • 对@GabeSpradlin 的赞赏规范稍作更正:我相信他们在这次迭代中取消了 orderBookRemove(证据:“o”+1 消息指定了一个卷,它并不总是 0)。因此,对于“o”消息,0 是询价,1 是修改出价(证据:根据经验数据推断,0/1 与这些渠道提供的订单簿快照中的询价/出价指数相匹配)。
    • 还有一个补充:["i",{"currencyPair":"BTC_XMR","orderBook":[{"0.02427000":"18.91841222","0.02431500":"0.16475174", ...}, {...}]}]。这似乎是一开始就检索到的inital 消息。所有其他数据只是更新。如您所见,它显示了发送的对以及该对的整个订单簿(包含 2 个对象的数组:出价/要价)
    【解决方案2】:

    您想要完成的工作可以通过使用WAMP 来完成,特别是通过使用高速公路库的 WAMP 模块(您已经在尝试使用)。

    遵循他们的文档后,我设法使用 autobahn 和 asyncio 设置了一个简单的示例。以下示例订阅“ticker”提要并打印接收到的值:

    from autobahn.asyncio.wamp import ApplicationSession
    from autobahn.asyncio.wamp import ApplicationRunner
    from asyncio import coroutine
    
    
    class PoloniexComponent(ApplicationSession):
        def onConnect(self):
            self.join(self.config.realm)
    
        @coroutine
        def onJoin(self, details):
            def onTicker(*args):
                print("Ticker event received:", args)
    
            try:
                yield from self.subscribe(onTicker, 'ticker')
            except Exception as e:
                print("Could not subscribe to topic:", e)
    
    
    def main():
        runner = ApplicationRunner("wss://api.poloniex.com:443", "realm1")
        runner.run(PoloniexComponent)
    
    
    if __name__ == "__main__":
        main()
    

    您可以在此处找到有关使用高速公路进行 WAMP 编程的更多详细信息:http://autobahn.ws/python/wamp/programming.html

    【讨论】:

    • 来自 self.subscribe(onTicker, 'ticker') SyntaxError: invalid syntax
    • 您使用的是哪个 Python 版本?此示例适用于 Python 3.3+,因为它使用 asyncioyield from 构造将执行委托给不同的协程。您可以在这里找到更多详细信息:docs.python.org/3/library/asyncio-task.html
    • 由于 runner 创建并处理了 PoloniexComponent 的实例,我们没有太多的访问权限。您是否知道一种向它添加回调以便另一个对象可以接收更新的方法?我更喜欢一种不使用某种全局通知调度的方法。
    • 我想通了。您可以通过 ApplicationRunner 的 extra 字典传递一个对象,然后在 PoloniexComponent 中通过 self.config.extra 访问它。
    • 此方法已过时。我认为 Poloniex 目前不支持此端点。请参阅下面的答案。
    【解决方案3】:

    同时 poloniex 更改了ticker API,所以现在它返回一个符号ID而不是名称,所以也许有人会发现这很有用:

    7: BTC_BCN
    8: BTC_BELA
    10: BTC_BLK
    12: BTC_BTCD
    13: BTC_BTM
    14: BTC_BTS
    15: BTC_BURST
    20: BTC_CLAM
    24: BTC_DASH
    25: BTC_DGB
    27: BTC_DOGE
    28: BTC_EMC2
    31: BTC_FLDC
    32: BTC_FLO
    38: BTC_GAME
    40: BTC_GRC
    43: BTC_HUC
    50: BTC_LTC
    51: BTC_MAID
    58: BTC_OMNI
    61: BTC_NAV
    63: BTC_NEOS
    64: BTC_NMC
    69: BTC_NXT
    73: BTC_PINK
    74: BTC_POT
    75: BTC_PPC
    83: BTC_RIC
    89: BTC_STR
    92: BTC_SYS
    97: BTC_VIA
    98: BTC_XVC
    99: BTC_VRC
    100: BTC_VTC
    104: BTC_XBC
    108: BTC_XCP
    112: BTC_XEM
    114: BTC_XMR
    116: BTC_XPM
    117: BTC_XRP
    121: USDT_BTC
    122: USDT_DASH
    123: USDT_LTC
    124: USDT_NXT
    125: USDT_STR
    126: USDT_XMR
    127: USDT_XRP
    129: XMR_BCN
    130: XMR_BLK
    131: XMR_BTCD
    132: XMR_DASH
    137: XMR_LTC
    138: XMR_MAID
    140: XMR_NXT
    148: BTC_ETH
    149: USDT_ETH
    150: BTC_SC
    151: BTC_BCY
    153: BTC_EXP
    155: BTC_FCT
    158: BTC_RADS
    160: BTC_AMP
    162: BTC_DCR
    163: BTC_LSK
    166: ETH_LSK
    167: BTC_LBC
    168: BTC_STEEM
    169: ETH_STEEM
    170: BTC_SBD
    171: BTC_ETC
    172: ETH_ETC
    173: USDT_ETC
    174: BTC_REP
    175: USDT_REP
    176: ETH_REP
    177: BTC_ARDR
    178: BTC_ZEC
    179: ETH_ZEC
    180: USDT_ZEC
    181: XMR_ZEC
    182: BTC_STRAT
    183: BTC_NXC
    184: BTC_PASC
    185: BTC_GNT
    186: ETH_GNT
    187: BTC_GNO
    188: ETH_GNO
    189: BTC_BCH
    190: ETH_BCH
    191: USDT_BCH
    192: BTC_ZRX
    193: ETH_ZRX
    194: BTC_CVC
    195: ETH_CVC
    196: BTC_OMG
    197: ETH_OMG
    198: BTC_GAS
    199: ETH_GAS
    200: BTC_STORJ
    

    【讨论】:

      【解决方案4】:

      目前,Twisted 没有正确使用 Windows 信任库。所以TLS证书的验证会失败。要解决此问题,直到 Twisted 或 Autobahn 包含解决方法,您可以:

      • 安装certifi模块(pip install certifi)
      • 设置 SSL_CERT_FILE,如export SSL_CERT_FILE="$(python -m certifi)"

      【讨论】:

      • 谢谢meejah。这在 Linux 下也有帮助。
      • Twisted 应该在 Linux 上使用全局信任库;也许您正在安装一个由于某种原因不包含它们的最小 Linux 安装?
      猜你喜欢
      • 1970-01-01
      • 2021-04-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-07
      相关资源
      最近更新 更多