使用Python调用BingX Swap Api遭遇HTTP Error 405: Method Not Allowed求助
调用BingX Swap API时HTTP Error 405: Method Not Allowed的解决办法
问题现象
调用BingX Swap的getLatestPrice接口时,抛出如下错误:
Traceback (most recent call last): File "Desktop\MyBot\MyApi.py", line 118, in <module> main() File "Desktop\MyBot\MyApi.py", line 103, in main print("getLatestPrice:", getLatestPrice()) ^^^^^^^^^^^^^^^^ File "Desktop\MyBot\MyApi.py", line 70, in getLatestPrice return post(url, paramsStr) ^^^^^^^^^^^^^^^^^^^^ File "Desktop\MyBot\MyApi.py", line 19, in post return urllib.request.urlopen(req).read() ^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "Python\Python311\Lib\urllib\request.py", line 216, in urlopen return opener.open(url, data, timeout) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "Python\Python311\Lib\urllib\request.py", line 525, in open response = meth(req, response) ^^^^^^^^^^^^^^^^^^^ File "Python\Python311\Lib\urllib\request.py", line 634, in http_response response = self.parent.error( ^^^^^^^^^^^^^^^^^^ File "Python\Python311\Lib\urllib\request.py", line 563, in error return self._call_chain(*args) ^^^^^^^^^^^^^^^^^^^^^^^ File "Python\Python311\Lib\urllib\request.py", line 496, in _call_chain result = func(*args) ^^^^^^^^^^^ File "Python\Python311\Lib\urllib\request.py", line 643, in http_error_default raise HTTPError(req.full_url, code, msg, hdrs, fp) urllib.error.HTTPError: HTTP Error 405: Method Not Allowed
原代码如下:
import urllib.request import json import base64 import hmac import time APIURL = "https://api-swap-rest.bingbon.pro" APIKEY = "xxxxxxxxxxxxx" SECRETKEY = "xxxxxxxxxxxxx" def genSignature(path, method, paramsMap): sortedKeys = sorted(paramsMap) paramsStr = "&".join(["%s=%s" % (x, paramsMap[x]) for x in sortedKeys]) paramsStr = method + path + paramsStr return hmac.new(SECRETKEY.encode("utf-8"), paramsStr.encode("utf-8"), digestmod="sha256").digest() def post(url, body): req = urllib.request.Request(url, data=body.encode("utf-8"), headers={'User-Agent': 'Mozilla/5.0'}) return urllib.request.urlopen(req).read() def getLatestPrice(): paramsMap = { "symbol": "BTC-USDT", } sortedKeys = sorted(paramsMap) paramsStr = "&".join(["%s=%s" % (x, paramsMap[x]) for x in sortedKeys]) paramsStr += "&sign=" + urllib.parse.quote(base64.b64encode(genSignature("/api/v1/market/getLatestPrice", "GET", paramsMap))) url = "%s/api/v1/market/getLatestPrice" % APIURL return post(url, paramsStr) def main(): print("getLatestPrice:", getLatestPrice()) if __name__ == "__main__": main()
错误原因
- 请求方法不匹配:
/api/v1/market/getLatestPrice是GET接口,但代码用POST请求发送参数,服务器返回405方法不允许错误。 - 参数传递方式错误:GET接口的参数必须拼接在URL的查询字符串中,不能放在POST请求体里。
修正方案
- 将请求方法改为GET,把参数(包括签名)拼接到URL末尾。
- 调整请求函数,适配GET请求的逻辑。
修正后的完整代码:
import urllib.request import urllib.parse import base64 import hmac APIURL = "https://api-swap-rest.bingbon.pro" APIKEY = "xxxxxxxxxxxxx" SECRETKEY = "xxxxxxxxxxxxx" def genSignature(path, method, paramsMap): sortedKeys = sorted(paramsMap) paramsStr = "&".join(["%s=%s" % (x, paramsMap[x]) for x in sortedKeys]) paramsStr = method + path + paramsStr return hmac.new(SECRETKEY.encode("utf-8"), paramsStr.encode("utf-8"), digestmod="sha256").digest() def get(url): req = urllib.request.Request(url, headers={'User-Agent': 'Mozilla/5.0'}) return urllib.request.urlopen(req).read() def getLatestPrice(): paramsMap = { "symbol": "BTC-USDT", } # 生成签名并编码 sign_bytes = genSignature("/api/v1/market/getLatestPrice", "GET", paramsMap) sign = urllib.parse.quote(base64.b64encode(sign_bytes)) # 拼接参数和签名到URL查询字符串 params_list = [f"{k}={v}" for k, v in paramsMap.items()] params_list.append(f"sign={sign}") params_str = "&".join(params_list) url = f"{APIURL}/api/v1/market/getLatestPrice?{params_str}" return get(url) def main(): print("getLatestPrice:", getLatestPrice()) if __name__ == "__main__": main()
额外说明
- 调用BingX接口前需确认文档指定的请求方法:公开市场接口多为GET,参数放URL查询字符串;私有交易接口可能需POST,参数放请求体。
- 签名生成逻辑需保证签名时使用的请求方法与实际请求方法完全一致,否则会导致签名验证失败。
内容的提问来源于stack exchange,提问作者Matias Paz
相关产品推荐
相关产品推荐

