435

I am getting a bit of headache just because a simple looking, easy statement is throwing some errors in my face.

I have a json file called strings.json like this:

"strings": [{"-name": "city", "#text": "City"}, {"-name": "phone", "#text": "Phone"}, ...,
            {"-name": "address", "#text": "Address"}]

I want to read the json file, just that for now. I have these statements which I found out, but it's not working:

import json
from pprint import pprint

with open('strings.json') as json_data:
    d = json.loads(json_data)
    json_data.close()
    pprint(d)

The error displayed on the console was this:

Traceback (most recent call last):
  File "/home/.../android/values/manipulate_json.py", line 5, in <module>
    d = json.loads(json_data)
  File "/usr/lib/python2.7/json/__init__.py", line 326, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/python2.7/json/decoder.py", line 366, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
TypeError: expected string or buffer
[Finished in 0.1s with exit code 1]

If I use json.load instead of json.loads, I get this error:

Traceback (most recent call last):
  File "/home/.../android/values/manipulate_json.py", line 5, in <module>
    d = json.load(json_data)
  File "/usr/lib/python2.7/json/__init__.py", line 278, in load
    **kw)
  File "/usr/lib/python2.7/json/__init__.py", line 326, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/python2.7/json/decoder.py", line 369, in decode
    raise ValueError(errmsg("Extra data", s, end, len(s)))
ValueError: Extra data: line 829 column 1 - line 829 column 2 (char 18476 - 18477)
[Finished in 0.1s with exit code 1]
R.R.C.
  • 4,817
  • 3
  • 13
  • 17
  • 7
    Are you sure that the file contains valid JSON? – Explosion Pills Nov 25 '13 at 17:16
  • 1
    possible duplicate of [Parsing values from a JSON file in Python](http://stackoverflow.com/questions/2835559/parsing-values-from-a-json-file-in-python) – AncientSwordRage May 19 '15 at 09:39
  • See also: [Read & Write example for JSON](http://stackoverflow.com/a/37795053/562769) – Martin Thoma Mar 09 '17 at 10:50
  • Your file is an invalid json format. Change it to: `{"strings": [{"-name": "city", "#text": "City"}, {"-name": "phone", "#text": "Phone"}, ..., {"-name": "address", "#text": "Address"}]}` – krizex Nov 27 '18 at 09:11
  • ...i.e. the thing that's invalid about the input is that it's missing the surrounding {} braces. – smci Mar 11 '22 at 20:22

7 Answers7

719

The json.load() method (without "s" in "load") can read a file directly:

import json

with open('strings.json') as f:
    d = json.load(f)
    print(d)

You were using the json.loads() method, which is used for string arguments only.


The error you get with json.loads is a totally different problem. In that case, there is some invalid json in that file. For that, I would recommend running the file through a json validator.

There are also solutions for fixing json like for example How do I automatically fix an invalid JSON string?

ubomb
  • 8,498
  • 2
  • 18
  • 24
  • 2
    hm...I changed from json.loads to json.load but I get that nice msg. – R.R.C. Nov 25 '13 at 17:23
  • 7
    Ah, well the new message is a totally different problem. In that case, there is some invalid json in that file. For that, I would recommend running the file through a [json validator](http://jsonlint.com/). – ubomb Nov 25 '13 at 17:26
  • 3
    got it! The file was missing EOF. The file was not correctly ended. I wouldn't notice that if it wasn't your good recommendation! Thanks! – R.R.C. Nov 25 '13 at 17:32
  • I must open file with byte flag, then I can use json.load method, why? I got Py3.6 – Grzegorz Krug Sep 29 '19 at 15:32
  • @GrzegorzKrug No sorry. But the [json.loads() documentation](https://docs.python.org/3/library/json.html#json.load) indicates that it accepts a text or binary file, so you should be fine doing it that way. – ubomb Sep 30 '19 at 14:27
  • That's so weird!!! I figured with `json.load`, you'd be able to pass it a file name, but you have to pass it an open file pointer!!! What the heck? – Shmack Jun 21 '21 at 17:30
118

Here is a copy of code which works fine for me

import json

with open("test.json") as json_file:
    json_data = json.load(json_file)
    print(json_data)

with the data

{
    "a": [1,3,"asdf",true],
    "b": {
        "Hello": "world"
    }
}

you may want to wrap your json.load line with a try catch because invalid JSON will cause a stacktrace error message.

user1876508
  • 12,542
  • 21
  • 65
  • 105
46

The problem is using with statement:

with open('strings.json') as json_data:
    d = json.load(json_data)
    pprint(d)

The file is going to be implicitly closed already. There is no need to call json_data.close() again.

Corey Goldberg
  • 56,214
  • 26
  • 121
  • 139
Zongjun
  • 589
  • 4
  • 7
33

In python 3, we can use below method.

Read from file and convert to JSON

import json
from pprint import pprint

# Considering "json_list.json" is a json file

with open('json_list.json') as fd:
     json_data = json.load(fd)
     pprint(json_data)

with statement automatically close the opened file descriptor.


String to JSON

import json
from pprint import pprint

json_data = json.loads('{"name" : "myName", "age":24}')
pprint(json_data)
Thejesh PR
  • 765
  • 7
  • 14
3

To add on this, today you are able to use pandas to import json:
https://pandas.pydata.org/pandas-docs/stable/generated/pandas.read_json.html You may want to do a careful use of the orient parameter.

Ando Jurai
  • 979
  • 2
  • 11
  • 29
3

You can use pandas library to read the JSON file.

import pandas as pd
df = pd.read_json('strings.json',lines=True)
print(df)
drorhun
  • 438
  • 3
  • 16
-3
def read_JSON():
    with open("FILE PATH", "r") as i:
        JSON_data = i.read()
    print(JSON_data)
Pushparaj
  • 74
  • 4
  • 2
    All this does is open the JSON file and read it into a variable, not parsing it; are you sure this is what OP wants? – TheTechRobo Stands for Ukraine Mar 19 '21 at 15:55
  • Yes, this will help to read JSON objects to utilize them as a request payload or for any other purpose. I am using this for my current API request implementation and it is working fine for me. – Pushparaj Mar 19 '21 at 22:59
  • If you have to parse the file, then `.read` would be a bad way of doing it, since you'll have to reimplement what the json module already does. – Gino Mempin Mar 20 '21 at 01:20
  • I think LOAD will reimplement the JSON with python dictionary but READ helps to load the JSON directly to the data frame – Pushparaj Mar 20 '21 at 12:34