LOADING...
LOADING...
LOADING...
当前位置: 玩币族首页 > 币圈百科 > 一个小错误引发的对Python列表、字典中元素各种拼接的探讨&AOFEX交易所API认证

一个小错误引发的对Python列表、字典中元素各种拼接的探讨&AOFEX交易所API认证

2020-09-17 杨卫祥 来源:区块链网络


这两天在调试一个交易所Aofex的API认证时,发现利用说明文档获得签名认证后,

def sign(Token,secret_key, Nonce,data=dict()):

tmp = list()

tmp.append(Token)

tmp.append(secret_key)

tmp.append(Nonce)

for d, x in data.items():

tmp.append(str(d) + "=" + str(x))

tmp = (''.join(sorted(tmp)))

tmp = tmp.encode("utf8")

return hashlib.sha1(tmp).hexdigest()

再来获取用户资产

AF_URL = 'https://openapi.aofex.com’

timestamp = int(time.time())

Nonce = str(timestamp)+'_'+str(int(random.uniform(10000, 99999))) # 随机数,客户端每次请求随机生成字符。生成规则,时间戳_5位随机字母或数字

url = AF_URL + '/openApi/wallet/list'

data = {'currency': 'ETH','show_all':'1'}

signature = sign(Token, secret_key, Nonce, data)

header = {'Nonce': Nonce,

'Token': Token,

'Signature': signature}

balance = request.get(url, data = data, headers=header)

print(balance)

无论如何都不成功,一直报错'api signature not valid’,根据这个提示,那就是认证不成功了,就从第一段程序中找各种原因。


来回试,反复试不行,找交易所客服咨询,他们给我一个验证签名是否正确的POST网址请求,我去验证后发现我自己与他们提供的方式计算的也不一样。

这时我更加怀疑我的认证有问题,但反复调试后还是不行。后来我就用他们直接验证过的签名signature直接调用,发现还是无法获取资产,这里我就开始怀疑其它问题了。

后来从他们网站提供认证的Nodejs示例中找到这么一条:url: 'https://openapi.aofex.com' + path + "?" + postMan,其中postMan是请求参数。

那意味着需要在url中添加请求参数了,按照这个思路我在请求资产中把参数设为空data={},然后把url后面加个问号?,一试果然成功了。

那问题就变成需要把请求参数data传到url中。传递的要求是在原始url中加?后再加请求参数,并以&作为分隔符。就是要把data = {'currency': 'ETH','show_all':'1'}变成currency=ETH&show_all=1,然后组成这样的url,https://openapi.aofex.com?currency=ETH&show_all=1


那么问题已经清楚了,怎么样把这个字典{'currency': 'ETH','show_all':'1’}中的元素变成currency=ETH&show_all=1?注意这里还需要排序。

Python中list,dict元素排序拼接问题原来挺糊涂的,常见问题列表:

如何对列表中元素排序

如何对列表中元素拼接,如何加字符比如&

如何把字典中元素转换为列表元素


这次要统一学习整理下,直接上例子一个个解释

'''列表中元素排序,拼接'''

tmp = ['a', 'b', '123', 'currency=ETH', 'show_all=1']

tmp = sorted(tmp) # 每个元素进行排序,结果['123', 'a', 'b', 'currency=ETH', 'show_all=1']

# tmp = (''.join(tmp)) # 排序后的元素连接到一起,什么都不加,结果123abcurrency=ETHshow_all=1

# print(tmp)

tmp = ('&'.join(tmp)) # 排序后的元素连接到一起,加&,结果123&a&b&currency=ETH&show_all=1

print(tmp)

'''字典中元素转换为列表元素'''

data = {'currency': 'ETH',

'show_all':'1'}

for d, x in data.items(): # 对字典中key:value取值

print(str(d) + "=" + str(x)) # 这里用字符=连接,结果 currency=ETH show_all=1

# tmp.append(str(d) + "=" + str(x))

'''列表,字典混合排序,拼接等操作’''

tmp = ['a', 'b', '123']

data = {'currency': 'ETH',

'show_all':'1'}

for d, x in data.items():

# print(str(d) + "=" + str(x)) # 结果 currency=ETH show_all=1

tmp.append(str(d) + "=" + str(x)) # 字典元素转换为列表元素,并添加到原来的列表中

print(tmp) # ['a', 'b', '123', 'currency=ETH', 'show_all=1']

# tmp = (''.join(sorted(tmp))) # 123abcurrency=ETHshow_all=1

tmp = ('&'.join(sorted(tmp))) # 123&a&b&currency=ETH&show_all=1

print(tmp)

'''如何从data = {'currency': 'ETH','show_all':'1'}变成currency=ETH&show_all=1'''

tmp = []

data = {'currency': 'ETH',

'show_all': '1'}

for d, x in data.items():

# print(str(d) + "=" + str(x)) # 结果 currency=ETH show_all=1

tmp.append(str(d) + "=" + str(x))

print(tmp) # ['currency=ETH', 'show_all=1']

tmp = ('&'.join(sorted(tmp))) # 拼接

print(tmp)

通过上面的例子,前面的问题也清楚了,那我只要在AOFEX获取资产的函数中更新下url就行了

AF_URL = 'https://openapi.aofex.com’

timestamp = int(time.time())

Nonce = str(timestamp)+'_'+str(int(random.uniform(10000, 99999))) # 随机数,客户端每次请求随机生成字符。生成规则,时间戳_5位随机字母或数字

url = AF_URL + '/openApi/wallet/list'

data = {'currency': 'ETH','show_all':'1'}

signature = sign(Token, secret_key, Nonce, data)

'''如何从data = {'currency': 'ETH','show_all':'1'}变成currency=ETH&show_all=1'''

tmp = []

for d, x in data.items():

# print(str(d) + "=" + str(x)) # 结果 currency=ETH show_all=1

tmp.append(str(d) + "=" + str(x))

# print(tmp) # ['currency=ETH', 'show_all=1']

tmp = ('&'.join(sorted(tmp)))

url = url + '?' + tmp

header = {'Nonce': Nonce,

'Token': Token,

'Signature': signature}

balance = request.get(url, data = data, headers=header)

print(balance)

到这里似乎问题已经解决了,但感觉哪里不对,balance = request.get(url, data = data, headers=header)中data传到了url,那data不就没用了吗?

于是继续查get(url, params=None, **kwargs),发现get原始函数中params而不是data,原来我用错了,于是把data=data改成params=data运行下没有返回错误,但也没有返回余额,这这这?

到底params=与data=啥区别?

继续搜索发现:

当发起一次GET请求时,params参数会以url string的形式进行传递。即?后的字符串则为其请求参数,并以&作为分隔符。

而data, json不会以url string的形式进行传递

我的天,原来是这样,我前面搞的字典中元素转化为列表再拼接白搞了,这其实就是params干的事,于是我把更新url那一段去掉,把最开始的data=data改成params=data,一切万事大吉了。

AF_URL ='https://openapi.aofex.com’
timestamp =int(time.time())
Nonce =str(timestamp)+'_'+str(int(random.uniform(10000,99999)))# 随机数,客户端每次请求随机生成字符。生成规则,时间戳_5位随机字母或数字
url = AF_URL +'/openApi/wallet/list'
data = {'currency':'ETH','show_all':'1'}
signature = sign(Token,secret_key,Nonce,data)
header = {'Nonce': Nonce,
'Token': Token,
'Signature': signature}
balance = request.get(url,params= data,headers=header)
print(balance)

—-

编译者/作者:杨卫祥

玩币族申明:玩币族作为开放的资讯翻译/分享平台,所提供的所有资讯仅代表作者个人观点,与玩币族平台立场无关,且不构成任何投资理财建议。文章版权归原作者所有。

LOADING...
LOADING...