代码之家  ›  专栏  ›  技术社区  ›  Andre Araujo

如何修复错误urllib.error.HTTPError:HTTP error 400:BAD REQUEST?

  •  2
  • Andre Araujo  · 技术社区  · 7 年前

    我有一个脚本(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 回复  |  直到 7 年前
        1
  •  1
  •   Andre Araujo    7 年前

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

    1. api应该是JSON_MIME_TYPE='application/JSON',所以我添加了 标题 在下面的请求中。
    2. scrit使用了错误的编码,因为JSON中的某些文本不能 编码 在Unicode中,例如:“OmÔ在ascii中编码启动异常 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