HTTPResponse object-l'objet JSON doit être str, pas 'bytes'

j'ai essayé de mettre à jour une petite bibliothèque Python appelé libpynexmo pour travailler avec Python 3.

je suis coincé sur cette fonction:

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

Quand il arrive à présent, json répond:

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

j'ai lu à quelques endroits que pour json.load vous devez passer des objets (Dans ce cas, un HTTPResponse objet) avec un .read() joint, mais il ne fonctionne pas sur HTTPResponse objets.

Je ne sais pas où aller avec ça, mais étant donné que tout mon script 1500 lignes est fraîchement converti en Python 3, je n'ai pas envie de revenir à la version 2.7.

24
demandé sur Zyerah 2014-06-05 23:59:29

4 réponses

j'ai récemment écrit une petite fonction pour envoyer des messages Nexmo. À moins que vous n'ayez besoin de toutes les fonctionnalités du code libpynexmo, cela devrait faire l'affaire pour vous. Et si vous voulez continuer à réviser libpynexmo, copiez ce code. La clé est l'encodage utf8.

si vous voulez envoyer d'autres champs avec votre message, la documentation complète pour ce que vous pouvez inclure avec un message de sortie nexmo ici

Python 3.4 testé Nexmo outbound (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']
17
répondu Ryan 2015-06-29 20:51:51

face au même problème je le résous en utilisant decode ()

...
rawreply = connection.getresponse().read()
reply = json.loads(rawreply.decode())
43
répondu costas 2014-07-01 18:41:48

j'ai rencontré le problème et maintenant il passe

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'))
8
répondu Du Peng 2015-12-27 15:27:33

puisque vous obtenez un HTTPResponse, vous pouvez utiliser Tornade.échapper et son json_decode() pour convertir le JSON strign en un dictionnaire:

from tornado import escape

body = escape.json_decode(body)

manuel:

tornade.échapper.la fonction json_decode(valeur)

renvoie des objets Python pour la chaîne JSON donnée.

2
répondu fedorqui 2016-03-23 12:29:09