求问 aiohttp 和 requests 库,产生的预期不一致。

2022-01-18 19:53:12 +08:00
 raycool

币安的批量撤单接口,发送 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())
3614 次点击
所在节点    Python
10 条回复
ThirdFlame
2022-01-18 20:13:17 +08:00
抓个包 瞅一瞅
wuwukai007
2022-01-18 20:15:31 +08:00
用 tornado 的 tornado.httpclient.AsyncHTTPClient 试试?
ClericPy
2022-01-18 22:44:58 +08:00
有现成的 params 参数为啥要手拼 URL...

土方法: 把 API 地址改成 http://httpbin.org/delete 再发一次看看返回有不一样么
locoz
2022-01-18 22:56:46 +08:00
还是那句说了一万遍的话:用统一的抓包工具抓个包对比一下,看看两个程序发出去的请求有什么区别
raycool
2022-01-18 23:01:22 +08:00
@locoz 这会正在用抓包工具测试,很奇葩,mac 下用的 proxyman ,为什么抓不到 aiohttp 的请求,requests 的倒是能抓到。
raycool
2022-01-18 23:02:40 +08:00
@ClericPy 这个历史遗留问题,刚好币安同时支持 query_string 这种模式, 其他的所有请求都是拼接成 url 来搞的,所以这个也这样写了。
raycool
2022-01-19 00:54:39 +08:00
@locoz 感谢老哥,终于解决了。
warcraft1236
2022-01-19 09:18:39 +08:00
其实就是 aiohttp 没给你转义?
bung
2022-01-19 10:11:52 +08:00
@ClericPy 是正解,不要手拼 URL ,用 params 参数不会出错。
另外,推荐 httpx ,同步异步都支持的
raycool
2022-01-19 11:20:15 +08:00
@warcraft1236 转义后的拼接成的 URL ,aiohttp 又给逗号转义回来了。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/829064

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX