如何修复错误urllib.error.HTTPError:HTTP错误400:错误请求?

时间:2018-08-06 05:19:24

标签: python-3.x http request urllib

我有一个脚本(test.py)来测试一些api,例如:

def get_response(fct, data, method=GET):
    """
    Performs the query to the server and returns a string containing the
    response.
    """
    assert(method in (GET, POST))
    url = f'http://{hostname}:{port}/{fct}'
    if method == GET:
        encode_data = parse.urlencode(data)
        response = request.urlopen(f'{url}?{encode_data}')
    elif method == POST:
        response = request.urlopen(url, parse.urlencode(data).encode('ascii'))
    return response.read()

在终端我打电话:

python test.py -H 0.0.0.0 -P 5000 --add-data

回溯:

Traceback (most recent call last):
  File "test.py", line 256, in <module>
    add_plays()
  File "test.py", line 82, in add_plays
    get_response("add_channel", {"name": channel}, method=POST)
  File "test.py", line 43, in get_response
    response = request.urlopen(url, parse.urlencode(data).encode('ascii'))
  File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/request.py", line 223, in urlopen
    return opener.open(url, data, timeout)
  File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/request.py", line 532, in open
    response = meth(req, response)
  File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/request.py", line 642, in http_response
    'http', request, response, code, msg, hdrs)
  File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/request.py", line 570, in error
    return self._call_chain(*args)
  File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/request.py", line 504, in _call_chain
    result = func(*args)
  File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/request.py", line 650, in http_error_default
    raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 400: BAD REQUEST

数据为{“ name”:“ Channel1”}。我不明白怎么了。有人可以给我一些提示或显示有什么问题吗?

当我使用curl通话时,可以正常工作:

curl -X POST -H "Content-Type: application/json" -d  '{"name": "Channel1"}' http://0.0.0.0:5000/add_channel

1 个答案:

答案 0 :(得分:1)

我解决了更改测试脚本的问题:

  1. 该API应该是JSON_MIME_TYPE ='application / json',因此我在请求中添加了 header ,如下所示。
  2. scrit使用了错误的编码,因为JSON中的某些文本无法用Unicode进行编码,例如:ascii中的“Omö”编码会启动 UnicodeEncodeError:'ascii'编解码器异常无法在位置1处编码字符“ \ xf6”:顺序号不在范围(128)中。所以我改为 utf8

这是固定代码:

def get_response(fct, data, method=GET):
    """
    Performs the query to the server and returns a string containing the
    response.
    """
    assert(method in (GET, POST))
    url = f'http://{hostname}:{port}/{fct}'
    if method == GET:
        encode_data = parse.urlencode(data)
        req = request.Request(f'{url}?{encode_data}'
                            , headers={'content-type': 'application/json'})
        response = request.urlopen(req)
    elif method == POST:
        params = json.dumps(data)
        binary_data = params.encode('utf8')
        req = request.Request(url
                            , data= binary_data
                            , headers={'content-type': 'application/json'})
        response = request.urlopen(req)
    x = response.read()
    return x