You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python2转Python3对接Poloniex交易API遇TypeError问题求助

排查Python3下Poloniex交易代码的TypeError问题

我帮你仔细梳理了这段迁移后的代码,里面有好几处Python2到Python3的适配错误,正是这些问题导致了你碰到的TypeError: not a valid non-string sequence or mapping object报错,咱们逐个修正:

1. urllib.parse.urlencode的用法完全错误

你写的post_data=urllib.parse.urlencode('utf-8')完全不符合这个方法的要求:

  • urlencode需要传入字典格式的请求参数(也就是你定义的req字典),而不是编码字符串
  • Python3中urlencode返回的是字符串,要用于HMAC签名,必须先编码成字节流

修正写法:

post_data = urllib.parse.urlencode(req).encode('utf-8')

2. 请求头(headers)的编码操作错误

你尝试对字典类型的headers执行encode('utf-8'),这是完全没必要的——urllib.request接受字典格式的headers,不需要手动编码,而且字典本身也不能直接调用encode方法。

修正写法:

headers = {
    'sign': sign,
    'key': self.APIKey
}

3. 请求构造与发送的代码完全误用了API

你把urllib.parse.urlencode当成了发送请求的方法,这是混淆了模块功能:

  • urlencode只是用来编码请求参数的,发送请求需要用urllib.request.Request构造请求对象,再用urllib.request.urlopen发送

修正后的请求构造代码:

# 构造请求对象
req_obj = urllib.request.Request(
    url='https://poloniex.com/tradingApi',
    data=post_data,
    headers=headers
)
# 发送请求并获取响应
ret = urllib.request.urlopen(req_obj)

4. 遗漏了urlopen的必填参数

你写的ret = urllib.request.urlopen()没有传入任何参数,这必然会触发参数错误,必须传入上面构造好的req_obj对象。

完整修正后的代码片段

把这些修正点整合后,代码应该是这样的:

import urllib.parse
import urllib.request
import hmac
import hashlib
import time
import json

# 假设这是类中的方法
def your_trading_method(self, command):
    req = {}
    req['command'] = command
    req['nonce'] = int(time.time()*1000)
    # 正确编码请求参数
    post_data = urllib.parse.urlencode(req).encode('utf-8')
    # 生成签名(注意Secret需要是字节流,如果你的Secret是字符串要先encode)
    sign = hmac.new(self.Secret.encode('utf-8') if isinstance(self.Secret, str) else self.Secret, 
                    post_data, 
                    hashlib.sha512).hexdigest()
    # 正确定义请求头
    headers = {
        'sign': sign,
        'key': self.APIKey
    }
    # 构造并发送请求
    req_obj = urllib.request.Request('https://poloniex.com/tradingApi', data=post_data, headers=headers)
    ret = urllib.request.urlopen(req_obj)
    # 解析响应:Python3中read()返回字节,要解码成字符串
    jsonRet = json.loads(ret.read().decode('utf-8'))
    return self.post_process(jsonRet)

额外注意点

  • 你的self.Secret如果是字符串类型,必须先编码成字节流才能传给hmac.new(),否则也会触发错误
  • ret.read()在Python3中返回的是字节对象,需要用decode('utf-8')转成字符串后再传给json.loads()

内容的提问来源于stack exchange,提问作者Adeel Janjua

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:40:34