¿Cómo embellecer JSON en Python?

99

¿Alguien puede sugerir cómo puedo embellecer JSON en Python o mediante la línea de comandos?

El único embellecedor JSON en línea que podía hacerlo era: http://jsonviewer.stack.hu/ .

Sin embargo, necesito usarlo desde Python.

Este es mi conjunto de datos:

{ "head": {"vars": [ "address" , "description" ,"listprice" ]} , "results": { "bindings": [ 
    {
        "address" : { "type":"string", "value" : " Dyne Road, London NW6"},
            "description" :{ "type":"string", "value" : "6 bed semi detached house"},
            "listprice" : { "type":"string", "value" : "1,150,000"}
    }
    ,
        {
            "address" : { "type":"string", "value" : " Tweedy Road, Bromley BR1"},
            "description" :{ "type":"string", "value" : "5 bed terraced house"},
            "listprice" : { "type":"string", "value" : "550,000"}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Vera Avenue, London N21"},
            "description" :{ "type":"string", "value" : "4 bed detached house"},
            "listprice" : { "type":"string", "value" : "

                995,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Wimbledon Park Side, London SW19"},
            "description" :{ "type":"string", "value" : "3 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Westbere Road, West Hampstead, London NW2"},
            "description" :{ "type":"string", "value" : "5 bedroom  semi detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " The Avenue, Hatch End, Pinner HA5"},
            "description" :{ "type":"string", "value" : "5 bedroom  detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Princes Park Avenue, London NW11"},
            "description" :{ "type":"string", "value" : "4 bedroom  detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Canons Drive, Edgware HA8"},
            "description" :{ "type":"string", "value" : "4 bedroom  detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Westbere Road, West Hampstead NW2"},
            "description" :{ "type":"string", "value" : "5 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Haymills Estate, Ealing, London"},
            "description" :{ "type":"string", "value" : "5 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Dene Terrace Woodclyffe Drive, Chislehurst, Kent BR7"},
            "description" :{ "type":"string", "value" : "5 bedroom  terraced house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Dene Terrace Woodclyffe Drive, Chislehurst, Kent BR7"},
            "description" :{ "type":"string", "value" : "5 bedroom  semi detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Northwick Close, St John's Wood NW8"},
            "description" :{ "type":"string", "value" : "3 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Claremont Gardens, Surbiton KT6"},
            "description" :{ "type":"string", "value" : "13 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Dene Terrace Woodclyffe Drive, Chislehurst, Kent BR7"},
            "description" :{ "type":"string", "value" : "5 bedroom  end terrace house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Stamford Road, London N1"},
            "description" :{ "type":"string", "value" : "4 bedroom  terraced house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Stanhope Avenue, London N3"},
            "description" :{ "type":"string", "value" : "6 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Haymills Estate, Ealing, London"},
            "description" :{ "type":"string", "value" : "5 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Elms Crescent, London SW4"},
            "description" :{ "type":"string", "value" : "5 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Princes Park Avenue, London NW11"},
            "description" :{ "type":"string", "value" : "4 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Abbeville Road, London SW4"},
            "description" :{ "type":"string", "value" : "4 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Canons Drive, Edgware HA8"},
            "description" :{ "type":"string", "value" : "4 bedroom  detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Henson Avenue, Willesdon Green NW2"},
            "description" :{ "type":"string", "value" : "5 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Woodstock Road, London NW11"},
            "description" :{ "type":"string", "value" : "5 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Tamworth Street, London SW6"},
            "description" :{ "type":"string", "value" : "5 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Stanhope Avenue, Finchley, London"},
            "description" :{ "type":"string", "value" : "5 bedroom  semi detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " The Old Burlington, Church Street, London W4"},
            "description" :{ "type":"string", "value" : "3 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Ebury Close, Northwood HA6"},
            "description" :{ "type":"string", "value" : "4 bedroom  detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Middleton Road, London NW11"},
            "description" :{ "type":"string", "value" : "4 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Henson Avenue, Willesden Green NW2"},
            "description" :{ "type":"string", "value" : "5 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Huron Road, London SW17"},
            "description" :{ "type":"string", "value" : "6 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Corringway, Ealing W5"},
            "description" :{ "type":"string", "value" : "5 bedroom  detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Woodlands Avenue, New Malden KT3"},
            "description" :{ "type":"string", "value" : "5 bedroom  detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Gunnersbury Park Area, Ealing, London"},
            "description" :{ "type":"string", "value" : "6 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Blenheim Gardens, London, Brent NW2"},
            "description" :{ "type":"string", "value" : "6 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Creighton Road, London NW6"},
            "description" :{ "type":"string", "value" : "4 bedroom  terraced house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Plaistow Lane, Bromley BR1"},
            "description" :{ "type":"string", "value" : "7 bedroom  detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Greenfield Gardens, London NW2"},
            "description" :{ "type":"string", "value" : "4 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Hendon Avenue, London N3"},
            "description" :{ "type":"string", "value" : "3 bedroom  detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Peckham Park Road, London SE15"},
            "description" :{ "type":"string", "value" : "6 bedroom  semi detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Woodclyffe Drive, Chislehurst BR7"},
            "description" :{ "type":"string", "value" : "5 bedroom  house for sale"},
            "listprice" : { "type":"string", "value" : "

                From 1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Highwood Hill, Mill Hill, London"},
            "description" :{ "type":"string", "value" : "5 bedroom  detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Stanhope Avenue, London N3"},
            "description" :{ "type":"string", "value" : "5 bedroom  semi detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Kersley Mews, London SW11"},
            "description" :{ "type":"string", "value" : "3 bedroom  mews for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Ebury Close, Northwood HA6"},
            "description" :{ "type":"string", "value" : "4 bedroom  detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Ellesmere Road, Chiswick W4"},
            "description" :{ "type":"string", "value" : "6 bedroom  detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " The Avenue, Hatch End, Pinner, Middlesex"},
            "description" :{ "type":"string", "value" : "5 bedroom  detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Wandsworth, London SW18"},
            "description" :{ "type":"string", "value" : "6 bedroom  semi detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Carlton Road, New Malden KT3"},
            "description" :{ "type":"string", "value" : "4 bedroom  detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " St Mary's Mews, Ealing W5"},
            "description" :{ "type":"string", "value" : "3 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Ritherdon Road, Balham, London SW17"},
            "description" :{ "type":"string", "value" : "5 bedroom  semi detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Goldsmith Avenue, London W3"},
            "description" :{ "type":"string", "value" : "5 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Plaistow Lane, Bromley, Kent BR1"},
            "description" :{ "type":"string", "value" : "7 bedroom  detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ] } }
Khwaishien
fuente
6
Me encanta el título de la pregunta (embellecer) :)
Guy Avraham

Respuestas:

184

Desde la línea de comandos:

echo '{"one":1,"two":2}' | python -mjson.tool

que salidas:

{
    "one": 1, 
    "two": 2
}

Programmáticamente, el manual de Python describe JSON de impresión bonita :

>>> import json
>>> print json.dumps({'4': 5, '6': 7}, sort_keys=True, indent=4)
{
    "4": 5,
    "6": 7
}
Samat Jain
fuente
42

Utilice el indentargumento de la dumpsfunción en el módulo json .

De los documentos:

>>> import json
>>> print json.dumps({'4': 5, '6': 7}, sort_keys=True, indent=4)
{
    "4": 5,
    "6": 7
}
Etienne Perot
fuente
33

Una solución mínima en Python que colorea los datos json proporcionados a través de la línea de comando:

import sys
import json
from pygments import highlight, lexers, formatters

formatted_json = json.dumps(json.loads(sys.argv[1]), indent=4)
colorful_json = highlight(unicode(formatted_json, 'UTF-8'), lexers.JsonLexer(), formatters.TerminalFormatter())
print(colorful_json)

Inspirado por lo pjsonmencionado anteriormente. Este código debe pygmentsinstalarse.

Ejemplo de salida:

ingrese la descripción de la imagen aquí

arnuschky
fuente
Muy útil. Exactamente lo que estaba buscando: embellecer las salidas de datos JSON en ipython. Gracias.
ser
La mejor respuesta aquí, también incluye una línea usando json.dumps () Usándola con aiohttp en python3.7, no necesitaba usar el módulo sys y unicode (String, encoding). Básicamente se convierte en == highlight (formatted_json, lexers.JsonLexer (), formatters.TerminalFormatter ())
DanglingPointer
2
con Python3, solo necesitaba eliminar la llamada unicode () ya que las cadenas son Unicode por defecto en Python3.
Open Food Broker
Solución agradable y fácil.
Sayantan
17

Pruebe el subrayado-cli :

cat myfile.json | underscore print --color

Es una herramienta bastante ingeniosa que puede manipular con elegancia muchos datos estructurados, ejecutar fragmentos js, rellenar plantillas, etc. Está ridículamente bien documentado, pulido y listo para un uso serio. Y lo escribí. :)

Dave Dopson
fuente
14

El comando cli que he usado con Python para esto es:

cat myfile.json | python -mjson.tool

Debería poder encontrar más información aquí:

http://docs.python.org/library/json.html

Herms
fuente
Ese es otro ejemplo desafortunado de abuso felino. Se puede lograr el mismo resultado sin crear un proceso separado y un montón de copias de memoria gratuitas con un simplepython -mjson.tool < myfile.json
Mikhail
1
¿Quizás me gusta alimentar a mis gatos? : P
Herms
Funciona muy bien con vim al sangrar la línea actual:.!python -mjson.tool
shuva
8

Parece que jsbeautifier abrió sus herramientas y las empaquetó como libs Python y JS, y como herramientas CLI. No parece que llamen a un servicio web, pero no lo revisé demasiado de cerca. Consulte el repositorio de github con las instrucciones de instalación.


De sus documentos para el uso de la biblioteca y la CLI de Python:

Para embellecer usando Python:

$ pip install jsbeautifier
$ js-beautify file.js

La salida embellecida va a stdout.

Usar jsbeautifiercomo biblioteca es simple:

import jsbeautifier
res = jsbeautifier.beautify('your javascript string')
res = jsbeautifier.beautify_file('some_file.js')

... o, para especificar algunas opciones:

opts = jsbeautifier.default_options()
opts.indent_size = 2
res = jsbeautifier.beautify('some javascript', opts)

Si desea pasar una cadena en lugar de un nombre de archivo, y está usando bash, entonces puede usar la sustitución de procesos así:

$ js-beautify <(echo '{"some": "json"}')
Dan Ross
fuente
7

No me gustó la salida de json.dumps (...) -> Para mi gusto, demasiadas líneas nuevas. Y no quería usar una herramienta de línea de comandos o instalar algo. Finalmente encontré Pythons pprint (= pretty print). Desafortunadamente, no genera JSON adecuado, pero creo que es útil tener un glympse fácil de usar en los datos almacenados.

Salida de json.dumps(json_dict, indent=4)

{
    "hyperspace": {
        "constraints": [],
        "design": [
            [
                "windFarm.windparkSize.k",
                "continuous",
                [
                    0,
                    0,
                    5
                ]
            ],
            [
                "hydroPlant.primaryControlMax",
                "continuous",
                [
                    100,
                    300
                ]
            ]
        ],
        "kpis": [
            "frequency.y",
            "city.load.p[2]"
        ]
    },
    "lhc_size": 10,
    "number_of_runs": 10
}

Uso de pprint:

import pprint

json_dict = {"hyperspace": {"constraints": [], "design": [["windFarm.windparkSize.k", "continuous", [0, 0, 5]], ["hydroPlant.primaryControlMax", "continuous", [100, 300]]], "kpis": ["frequency.y", "city.load.p[2]"]}, "lhc_size": 10, "number_of_runs": 10}

formatted_json_str = pprint.pformat(json_dict)
print(formatted_json_str)
pprint.pprint(json_dict)

Resultado de pprint.pformat(...)o pprint.pprint(...):

{'hyperspace': {'constraints': [],
                'design': [['windFarm.windparkSize.k', 'continuous', [0, 0, 5]],
                           ['hydroPlant.primaryControlMax',
                            'continuous',
                            [100, 300]]],
                'kpis': ['frequency.y', 'city.load.p[2]']},
 'lhc_size': 10,
 'number_of_runs': 10}
XiO
fuente
5
alias jsonp='pbpaste | python -m json.tool'

Esto imprimirá bastante JSON que está en el portapapeles en OSX. Simplemente cópielo y luego llame al alias desde un indicador de Bash.

Davidbitton
fuente
5

Puede canalizar la salida a jq. Si su secuencia de comandos de Python contiene algo como

print json.dumps(data)

entonces puedes disparar:

python foo.py | jq '.'
Dror
fuente
jq es una gran herramienta.
orion elenzil
2

Primero instale pygments

luego

echo '<some json>' | python -m json.tool | pygmentize -l json

Meng Zhao
fuente
1

Tus datos están mal formados. Los campos de valor, en particular, tienen numerosos espacios y nuevas líneas. Los formateadores automáticos no funcionarán en esto, ya que no modificarán los datos reales. A medida que genera los datos para la salida, fíltrelos según sea necesario para evitar los espacios.

zim2411
fuente
0

Con jsonlint (como xmllint):

aptitude install python-demjson
jsonlint -f foo.json
Jim
fuente