Using the following code I was able to open your JSON and print it. Save your JSON to temp.json and try this:
import json
with open("temp.json", "r") as infile:
data = json.loads(infile.read())
print(data)
Answer from mikeg on Stack Overflowpython - Handle JSON Decode Error when nothing returned - Stack Overflow
Bug: `JSONDecodeError` when trying to load JSON with an array at the top-level
Help: json.loads() cannot parse valid json
Why am I getting a JSONDecodeError when trying to load a JSON file in Python? - Stack Overflow
JSON doc:
{
"Data" : [
"input1",
"input2",
"input3",
"input4"
]
}Python code:
import json
with open("data.json", 'r') as f:
json_data = json.load(f)
print(json_data)Error message:
sh-5.1$ /bin/python /home/USER/Documents/Python/learning
Traceback (most recent call last):
File "/home/USER/Documents/Python/learning", line 27, in <module>
json_data = json.load(f)
File "/usr/lib/python3.9/json/__init__.py", line 293, in load
return loads(fp.read(),
File "/usr/lib/python3.9/json/__init__.py", line 346, in loads
return _default_decoder.decode(s)
File "/usr/lib/python3.9/json/decoder.py", line 337, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/lib/python3.9/json/decoder.py", line 355, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)Disproved theories: Improper syntax (python), document not located, bad formatting (json), accidental empty space in json.
I get this error each time I try to use "json.load" so long as it has a valid parameter input. Whether read or write; error. I'm using Visual Studio Code on Linux Mint in case that matters.
Thanks for your time! I'll be happy to answer questions in the morning when I wake up.
EDIT: Clarity, and reddit dislikes my use of backticks. Manually tabbed code.
EDIT: This code SHOULD work. It does on other computers. But it doesn't on mine, and I don't know why nor how to fix it.
There is a rule in Python programming called "it is Easier to Ask for Forgiveness than for Permission" (in short: EAFP). It means that you should catch exceptions instead of checking values for validity.
Thus, try the following:
try:
qByUser = byUsrUrlObj.read()
qUserData = json.loads(qByUser).decode('utf-8')
questionSubjs = qUserData["all"]["questions"]
except ValueError: # includes simplejson.decoder.JSONDecodeError
print('Decoding JSON has failed')
EDIT: Since simplejson.decoder.JSONDecodeError actually inherits from ValueError (proof here), I simplified the catch statement by just using ValueError.
If you don't mind importing the json module, then the best way to handle it is through json.JSONDecodeError (or json.decoder.JSONDecodeError as they are the same) as using default errors like ValueError could catch also other exceptions not necessarily connected to the json decode one.
from json.decoder import JSONDecodeError
try:
qByUser = byUsrUrlObj.read()
qUserData = json.loads(qByUser).decode('utf-8')
questionSubjs = qUserData["all"]["questions"]
except JSONDecodeError as e:
# do whatever you want
//EDIT (Oct 2020):
As @Jacob Lee noted in the comment, there could be the basic common TypeError raised when the JSON object is not a str, bytes, or bytearray. Your question is about JSONDecodeError, but still it is worth mentioning here as a note; to handle also this situation, but differentiate between different issues, the following could be used:
from json.decoder import JSONDecodeError
try:
qByUser = byUsrUrlObj.read()
qUserData = json.loads(qByUser).decode('utf-8')
questionSubjs = qUserData["all"]["questions"]
except JSONDecodeError as e:
# do whatever you want
except TypeError as e:
# do whatever you want in this case
Your code produced an empty response body; you'd want to check for that or catch the exception raised. It is possible the server responded with a 204 No Content response, or a non-200-range status code was returned (404 Not Found, etc.). Check for this.
Note:
There is no need to decode a response from UTF8 to Unicode, the
json.loads()method can handle UTF8-encoded data natively.pycurlhas a very archaic API. Unless you have a specific requirement for using it, there are better choices.
Either requests or httpx offer much friendlier APIs, including JSON support.
If you can, replace your call with the following httpx code:
import httpx
response = httpx.get(url)
response.raise_for_status() # raises exception when not a 2xx response
if response.status_code != 204:
return response.json()
Of course, this won't protect you from a URL that doesn't comply with HTTP standards; when using arbitrary URLs where this is a possibility, check if the server intended to give you JSON by checking the Content-Type header, and for good measure catch the exception:
if (
response.status_code != 204 and
response.headers["content-type"].strip().startswith("application/json")
):
try:
return response.json()
except ValueError:
# decide how to handle a server that's misbehaving to this extent
Be sure to remember to invoke json.loads() on the contents of the file, as opposed to the file path of that JSON:
json_file_path = "/path/to/example.json"
with open(json_file_path, 'r') as j:
contents = json.loads(j.read())
I think a lot of people are guilty of doing this every once in a while (myself included):
contents = json.load(json_file_path)
Iterate over the file, loading each line as JSON in the loop:
tweets = []
with open('tweets.json', 'r') as file:
for line in file:
tweets.append(json.loads(line))
This avoids storing intermediate python objects. As long as you write one full tweet per append() call, this should work.
As you can see in the following example, json.loads (and json.load) does not decode multiple json object.
>>> json.loads('{}')
{}
>>> json.loads('{}{}') # == json.loads(json.dumps({}) + json.dumps({}))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python27\lib\json\__init__.py", line 338, in loads
return _default_decoder.decode(s)
File "C:\Python27\lib\json\decoder.py", line 368, in decode
raise ValueError(errmsg("Extra data", s, end, len(s)))
ValueError: Extra data: line 1 column 3 - line 1 column 5 (char 2 - 4)
If you want to dump multiple dictionaries, wrap them in a list, dump the list (instead of dumping dictionaries multiple times)
>>> dict1 = {}
>>> dict2 = {}
>>> json.dumps([dict1, dict2])
'[{}, {}]'
>>> json.loads(json.dumps([dict1, dict2]))
[{}, {}]