Объект HTTPResponse - объект JSON должен быть str, а не "байтами"

Я пытался обновить небольшую библиотеку Python под названием libpynexmo для работы с 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 вы должны передать объекты (в этом случае HTTPResponse объект) с .read() прилагается, но он не работает на HTTPResponse объекты.

Я в недоумении, куда идти с этим дальше, но поскольку весь мой 1500-строчный скрипт недавно преобразован в Python 3, мне не хочется возвращаться к 2.7.

4 ответов


недавно я написал небольшую функцию для отправки сообщений 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']

столкнувшись с той же проблемой, я решаю ее с помощью decode ()

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

Я также встретил проблему, и теперь она проходит

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'))

Так как вы получаете HTTPResponse, вы можете использовать Торнадо.побег и json_decode() чтобы преобразовать JSON strign в словарь:

from tornado import escape

body = escape.json_decode(body)

из руководства:

торнадо.побег.json_decode(значение)

возвращает объекты Python для данной строки JSON.