MLam
MLam

Reputation: 171

python3 JSONDecodeError: Expecting value: line 1 column 1 (char 0)

I'm facing this error in python3.6.

My json file looks like this:

{
"id":"776", 
"text":"Scientists have just discovered a bizarre pattern in global weather. Extreme heat waves like the one that hit the Eastern US in 2012, leaving at least 82 dead, don't just come out of nowhere."
}

It's encoding 'utf-8' and I checked it online, it is a valid json file. I tried to load it in this way:

p = 'doc1.json'
json.loads(p)

I tried this as well:

p = "doc1.json"
with open(p, "r") as f:
    doc = json.load(f)

The error is the same:

JSONDecodeError: Expecting value: line 1 column 1 (char 0)

Anyone can help? Thank you!

Upvotes: 1

Views: 16990

Answers (2)

Jesse H.
Jesse H.

Reputation: 733

Aside

First, your path is not really a path. My response won't be about that, but your path should be something like '.path/to/the/doc1.json' (this example is a relative path).

TL;DR

json.loads is for loading str objects directly; json.load wants a fp or file pointer object which represents a file.

Solution

It appears you are misusing json.loads vs json.load (notice the s in one and not the other). I believe the s stands for string or Python object type str though I may be wrong. There is a very important distinction here; your path is represented by a string, but you actually care about the file as an object.

So of course this breaks because json.loads thinks it is trying to parse a type str object that is actually an invalid json:

path = 'a/path/like/this/is/a/string.json'
json.loads(path)
---------------------------------------------------------------------------
JSONDecodeError                           Traceback (most recent call last)
...
JSONDecodeError: Expecting value: line 1 column 1 (char 0)

Using this properly would look something like this:

json_str = '{"hello": "world!"}'
json.loads(json_str)

# The expected output.
{'hello': 'world!'}

Since json.loads does not meet our needs—it can, however it is extra and unnecessary code—we can use its friend json.load. json.load wants its first parameter to be an fp, but what is that? Well, it stands for file pointer which is a fancy way of saying "an object that represents a file." This has to do with opening a file to do something to or with it. In our case, we want to read the file into json.load.

We will use the context manager open() since that is a good thing to do. Note, I do not know what the contents of your doc1.json is so I replaced the output with my own.

path = 'path/to/the/doc1.json'
with open(path, 'r') as fp:
    print(json.load(fp))

# The expected output.
{'hello': 'world!'}

Generally, I think I would use json.load a lot more than json.loads (with the s) since I read directly from json files. If you load some json into your code using a third party package, you may find your self reading that in your code and then passing as a str to json.loads.

Resources

  1. Python's json — https://docs.python.org/3/library/json.html#module-json

Upvotes: 0

greg_data
greg_data

Reputation: 2293

p = 'doc1.json'
json.loads(p)

you're asking the json module to load the string 'doc1.json' which obviously isn't valid json, it's a filename.

You want to open the file, read the contents, then load the contents using json.loads():

p = 'doc1.json'
with open(p, 'r') as f:
    doc = json.loads(f.read())

As suggested in the comments, this could be further simplified to:

p = 'doc1.json'
with open(p, 'r') as f:
    doc = json.load(f)

where jon.load() takes a file handle and reads it for you.

Upvotes: 3

Related Questions