26

I've been trying to update a small Python library called libpynexmo to work with Python 3.

I've been stuck on this function:

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

When it gets to this, json responds with:

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

I read in a few places that for json.load you should pass objects (In this case an HTTPResponse object) with a .read() attached, but it doesn't work on HTTPResponse objects.

I'm at a loss as to where to go with this next, but being that my entire 1500 line script is freshly converted to Python 3, I don't feel like going back to 2.7.

4

4 回答 4

47

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

...
rawreply = connection.getresponse().read()
reply = json.loads(rawreply.decode())
于 2014-07-01T18:41:48.240 回答
17

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

如果您想在您的消息中发送任何其他字段,您可以在 nexmo 出站消息中包含的完整文档在这里

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']
于 2014-06-06T01:01:26.443 回答
13

我也遇到了这个问题,现在它通过了

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'))
于 2015-12-27T15:27:33.573 回答
3

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

from tornado import escape

body = escape.json_decode(body)

从手册:

tornado.escape.json_decode(值)

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

于 2016-03-23T12:29:09.457 回答