Convertir una matriz de bytes a formato JSON

Resuelto Merouane Benthameur asked hace 7 años • 9 respuestas

Quiero analizar una bytescadena en formato JSON para convertirla en objetos de Python. Esta es la fuente que tengo:

my_bytes_value = b'[{\'Date\': \'2016-05-21T21:35:40Z\', \'CreationDate\': \'2012-05-05\', \'LogoType\': \'png\', \'Ref\': 164611595, \'Classe\': [\'Email addresses\', \'Passwords\'],\'Link\':\'http://some_link.com\'}]'

Y este es el resultado deseado que quiero tener:

[{
"Date": "2016-05-21T21:35:40Z",
"CreationDate": "2012-05-05",
"LogoType": "png",
"Ref": 164611595,
"Classes": [
  "Email addresses",
  "Passwords"
],
"Link": "http://some_link.com"}]

Primero, convertí los bytes en cadena:

my_new_string_value = my_bytes_value.decode("utf-8")

pero cuando intento invocarlo loadspara analizarlo como JSON:

my_json = json.loads(my_new_string_value)

Recibo este error:

json.decoder.JSONDecodeError: Expecting value: line 1 column 174 (char 173)
Merouane Benthameur avatar Oct 15 '16 20:10 Merouane Benthameur
Aceptado

Su bytesobjeto es casi JSON, pero usa comillas simples en lugar de comillas dobles y debe ser una cadena. Entonces, una forma de solucionarlo es decodificar bytesy strreemplazar las comillas. Otra opción es utilizar ast.literal_eval; consulte a continuación para obtener más detalles. Si desea imprimir el resultado o guardarlo en un archivo como JSON válido, puede cargar el JSON en una lista de Python y luego eliminarlo. P.ej,

import json

my_bytes_value = b'[{\'Date\': \'2016-05-21T21:35:40Z\', \'CreationDate\': \'2012-05-05\', \'LogoType\': \'png\', \'Ref\': 164611595, \'Classe\': [\'Email addresses\', \'Passwords\'],\'Link\':\'http://some_link.com\'}]'

# Decode UTF-8 bytes to Unicode, and convert single quotes 
# to double quotes to make it valid JSON
my_json = my_bytes_value.decode('utf8').replace("'", '"')
print(my_json)
print('- ' * 20)

# Load the JSON to a Python list & dump it back out as formatted JSON
data = json.loads(my_json)
s = json.dumps(data, indent=4, sort_keys=True)
print(s)

producción

[{"Date": "2016-05-21T21:35:40Z", "CreationDate": "2012-05-05", "LogoType": "png", "Ref": 164611595, "Classe": ["Email addresses", "Passwords"],"Link":"http://some_link.com"}]
- - - - - - - - - - - - - - - - - - - - 
[
    {
        "Classe": [
            "Email addresses",
            "Passwords"
        ],
        "CreationDate": "2012-05-05",
        "Date": "2016-05-21T21:35:40Z",
        "Link": "http://some_link.com",
        "LogoType": "png",
        "Ref": 164611595
    }
]

Como menciona Antti Haapala en los comentarios, podemos usar ast.literal_evalpara convertir my_bytes_valuea una lista de Python, una vez que la hayamos decodificado en una cadena.

from ast import literal_eval
import json

my_bytes_value = b'[{\'Date\': \'2016-05-21T21:35:40Z\', \'CreationDate\': \'2012-05-05\', \'LogoType\': \'png\', \'Ref\': 164611595, \'Classe\': [\'Email addresses\', \'Passwords\'],\'Link\':\'http://some_link.com\'}]'

data = literal_eval(my_bytes_value.decode('utf8'))
print(data)
print('- ' * 20)

s = json.dumps(data, indent=4, sort_keys=True)
print(s)

Generalmente, este problema surge porque alguien guardó datos imprimiendo su Python repren lugar de usar el jsonmódulo para crear datos JSON adecuados. Si es posible, es mejor solucionar ese problema para que, en primer lugar, se creen datos JSON adecuados.

PM 2Ring avatar Oct 15 '2016 14:10 PM 2Ring

Puedes simplemente usar,

import json

my_bytes_value = my_bytes_value.decode().replace("'", '"')
json.loads(my_bytes_value)
Chaithanya Krishna avatar Oct 16 '2020 08:10 Chaithanya Krishna

Python 3.5 + Usar módulo io

import json
import io

my_bytes_value = b'[{\'Date\': \'2016-05-21T21:35:40Z\', \'CreationDate\': \'2012-05-05\', \'LogoType\': \'png\', \'Ref\': 164611595, \'Classe\': [\'Email addresses\', \'Passwords\'],\'Link\':\'http://some_link.com\'}]'

fix_bytes_value = my_bytes_value.replace(b"'", b'"')

my_json = json.load(io.BytesIO(fix_bytes_value))  
Novikov avatar Dec 16 '2020 19:12 Novikov
d = json.dumps(byte_str.decode('utf-8'))
Kwame avatar Apr 08 '2022 11:04 Kwame