币安的批量撤单接口,发送 DELETE 协议,进行批量撤单。
使用 aiohttp 进行撤单,也就是注释块 1 的那部分代码,直接返回签名无效。
而使用 requests 进行撤单,也就是注释块 2 的这部分代码,返回订单不存在,因为订单已经不存在了,所以返回订单不存在,符合预期,如果是有效的订单,会直接撤单成功。
很奇怪的是为什么两个库在 delete 协议有这样的差异,别的 post ,get 请求没问题。
import requests import hmac import hashlib import time import os from aiohttp import ClientSession import asyncio api_key = "网站的 apikey" secret_key = "网站的 secretkey" base_url = 'https://fapi.binance.com' symbol = "ETHUSDT" def _signature(params): params_query_string = urlencode(params) return hmac.new( secret_key.encode("utf-8"), params_query_string.encode("utf-8"), hashlib.sha256 ).hexdigest() async def _delete(url, params): headers = {"X-MBX-APIKEY": api_key, "Content-Type": "application/x-www-form-urlencoded", "Accept": "application/json"} params_encoded = urlencode(params) url = url + '?' + params_encoded #1 async with ClientSession() as session: #1 async with session.delete(url, headers=headers) as response: #1 text = await response.text() #1 print('result', text) #2 respOnse= requests.delete(url, headers=headers) #2 print('result', response.json()) def run(): params = { "symbol": symbol, "origClientOrderIdList": '["aaa-220117222620000008","aaa--220117222620000009"]', "timestamp": int(time.time()*1000) } params["signature"] = _signature(params) url = urljoin(base_url, "/fapi/v1/batchOrders") return _delete(url, params) loop = asyncio.get_event_loop() loop.run_until_complete(run())
破案了,确实是两个库对url中有些转义字符处理的规则不一致导致的。
其中对某种情况下包含特殊转义字符的话
aiohttp的库的url需要做特别的处理
from yarl import URL async with ClientSession() as session: async with session.delete(URL(url, encoded=True), headers=headers) as response: text = await response.text() print('result', text)
1 ThirdFlame 2022-01-18 20:13:17 +08:00 抓个包 瞅一瞅 |
![]() | 2 |
![]() | 3 ClericPy 2022-01-18 22:44:58 +08:00 |
![]() | 4 locoz 2022-01-18 22:56:46 +08:00 via Android 还是那句说了一万遍的话:用统一的抓包工具抓个包对比一下,看看两个程序发出去的请求有什么区别 |
5 raycool OP @locoz 这会正在用抓包工具测试,很奇葩,mac 下用的 proxyman ,为什么抓不到 aiohttp 的请求,requests 的倒是能抓到。 |
6 raycool OP @ClericPy 这个历史遗留问题,刚好币安同时支持 query_string 这种模式, 其他的所有请求都是拼接成 url 来搞的,所以这个也这样写了。 |
8 warcraft1236 2022-01-19 09:18:39 +08:00 其实就是 aiohttp 没给你转义? |
10 raycool OP @warcraft1236 转义后的拼接成的 URL ,aiohttp 又给逗号转义回来了。 |