【问题标题】:HTTPResponse object -- JSON object must be str, not 'bytes'HTTPResponse 对象——JSON 对象必须是 str,而不是 'bytes'
【发布时间】:2014-06-05 19:59:29
【问题描述】:

我一直在尝试更新一个名为 libpynexmo 的小型 Python 库以使用 Python 3。

我一直卡在这个功能上:

def send_request_json(self, request):
    url = request
    req =  urllib.request.Request(url=url)
    req.add_header('Accept', 'application/json')
    try:
        return json.load(urllib.request.urlopen(req))
    except ValueError:
        return False

当它到达这里时,json 会响应:

TypeError: the JSON object must be str, not 'bytes'

我在一些地方读到,对于 json.load,您应该传递带有 .read() 的对象(在本例中为 HTTPResponse 对象),但它不适用于 HTTPResponse 对象。

我不知道下一步该去哪里,但由于我的整个 1500 行脚本都刚刚转换为 Python 3,我不想回到 2.7。

【问题讨论】:

  • 解决方案见此处:stackoverflow.com/questions/6862770/…
  • 你试过通过2to3吗?
  • @zmo - 手动完成,以便了解更多信息。
  • @dano - 之前找到了该链接,但无法使他的解决方法适用于我的情况。我无法在我的 HTTPResponse 对象上使用 .readall()。
  • @Chevron,如果您尝试转换 json 请求对象,请使用:json.loads(request.body.decode('utf-8'))

标签: json python-3.x python-3.4 nexmo


【解决方案1】:

面对同样的问题,我使用 decode() 解决了它

...
rawreply = connection.getresponse().read()
reply = json.loads(rawreply.decode())

【讨论】:

  • 你能解释一下为什么这是必要的吗?
  • 查看this question 以获得解释
【解决方案2】:

我最近写了一个小函数来发送 Nexmo 消息。除非您需要 libpynexmo 代码的全部功能,否则这应该可以为您完成工作。如果您想继续检修 libpynexmo,只需复制此代码即可。关键是utf8编码。

如果您想在消息中发送任何其他字段,请参阅有关您可以在 nexmo 出站消息中包含的内容的完整文档is here

Python 3.4 测试 Nexmo 出站 (JSON):

def nexmo_sendsms(api_key, api_secret, sender, receiver, body):
    """
    Sends a message using Nexmo.

    :param api_key: Nexmo provided api key
    :param api_secret: Nexmo provided secrety key
    :param sender: The number used to send the message
    :param receiver: The number the message is addressed to
    :param body: The message body
    :return: Returns the msgid received back from Nexmo after message has been sent.
    """


    msg = {
        'api_key': api_key,
        'api_secret': api_secret,
        'from': sender,
        'to': receiver,
        'text': body
    }
    nexmo_url = 'https://rest.nexmo.com/sms/json'
    data = urllib.parse.urlencode(msg)
    binary_data = data.encode('utf8')
    req = urllib.request.Request(nexmo_url, binary_data)
    response = urllib.request.urlopen(req)
    result = json.loads(response.readall().decode('utf-8'))
    return result['messages'][0]['message-id']

【讨论】:

    【解决方案3】:

    我也遇到了这个问题,现在解决了

    import json
    import urllib.request as ur
    import urllib.parse as par
    
    html = ur.urlopen(url).read()
    print(type(html))
    data = json.loads(html.decode('utf-8'))
    

    【讨论】:

      【解决方案4】:

      由于您获得的是HTTPResponse,因此您可以使用Tornado.escape 及其json_decode() 将JSON 字符串转换为字典:

      from tornado import escape
      
      body = escape.json_decode(body)
      

      来自手册:

      tornado.escape.json_decode(值)

      返回给定 JSON 字符串的 Python 对象。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-07-10
        • 2017-08-31
        • 2023-03-13
        • 2021-06-17
        • 2017-11-01
        • 2019-08-04
        • 2019-08-27
        相关资源
        最近更新 更多