解決Python 中JSONDecodeError: Expecting value: line 1 column 1 (char 0)錯(cuò)誤
Python“json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0) ”發(fā)生在我們?cè)噲D解析一些無(wú)效的 JSON 時(shí)。
要解決該錯(cuò)誤,請(qǐng)確保響應(yīng)或文件不為空,或者在解析之前有條件地檢查內(nèi)容類型。
嘗試解析空字符串會(huì)導(dǎo)致錯(cuò)誤
這是一個(gè)非常簡(jiǎn)單的示例,說(shuō)明錯(cuò)誤是如何發(fā)生的。
import json
# ?? json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
result = json.loads('')
我們?cè)噲D將一個(gè)空字符串當(dāng)作有效的 JSON 來(lái)解析。
錯(cuò)誤的常見(jiàn)原因
最常見(jiàn)的錯(cuò)誤原因是:
- 嘗試解析無(wú)效的 JSON 值(例如單引號(hào)或尾隨逗號(hào))。
- 從遠(yuǎn)程服務(wù)器(例如 204 或 404)獲取空響應(yīng)并嘗試將其作為 JSON 進(jìn)行解析。
- 嘗試像解析 JSON 一樣解析具有不同內(nèi)容類型(例如文本/html)的響應(yīng)。
- 嘗試錯(cuò)誤地讀取 JSON 文件或嘗試解析空 JSON 文件的內(nèi)容。
嘗試解析無(wú)效的 JSON 值
下面是一個(gè)存儲(chǔ)無(wú)效 JSON 的文件示例。
example.json
{
"id": 1,
'name': "Alice",
"age": 30,
"country": "Austria"
}
請(qǐng)注意,名稱屬性用單引號(hào)引起來(lái)。
這會(huì)使 JSON 無(wú)效,并且嘗試從文件中讀取會(huì)導(dǎo)致錯(cuò)誤。
import json
file_name = 'example.json'
# ?? json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 3 column 3 (char 15)
with open(file_name, 'r', encoding='utf-8') as f:
my_data = json.load(f)
print(my_data)要解決該錯(cuò)誤,需要確保將 JSON 中的所有鍵和字符串值用雙引號(hào)引起來(lái)。
example.json
{
"id": 1,
"name": "Alice",
"age": 30,
"country": "Austria"
}現(xiàn)在 name 鍵用雙引號(hào)括起來(lái),我們可以安全地從文件中讀取。
# ? works as expected
import json
file_name = 'example.json'
with open(file_name, 'r', encoding='utf-8') as f:
my_data = json.load(f)
# ??? {'id': 1, 'name': 'Alice', 'age': 30, 'country': 'Austria'}
print(my_data)
print(my_data['name']) # ??? Alice確保在打開(kāi)文件時(shí)設(shè)置編碼關(guān)鍵字參數(shù)(如上面的代碼示例所示)。
忘記用引號(hào)括起屬性或字符串值
以下是無(wú)效和有效 JSON 值的一些示例。
example.json
// ?? 無(wú)效的 JSON(忘記引用屬性)
{
"name": "Alice",
age: 30
}對(duì)象中的 age 屬性未用雙引號(hào)引起來(lái),這使得 JSON 無(wú)效。
example.json
// ? 有效的 JSON(所有屬性都用雙引號(hào)引起來(lái))
{
"name": "Alice",
"age": 30
}示例中的 JSON 是有效的,因?yàn)樗袑傩院妥址刀加秒p引號(hào)引起來(lái)。
對(duì)屬性或值使用單引號(hào)而不是雙引號(hào)
確保沒(méi)有屬性或字符串值用單引號(hào)引起來(lái)。
example.json
// ?? 無(wú)效的 JSON(用單引號(hào)引起來(lái)的名稱屬性)
{
'name': "Alice",
"age": 30
}示例中的名稱屬性用單引號(hào)引起來(lái),這使得 JSON 無(wú)效。
永遠(yuǎn)不要在 JSON 中使用單引號(hào)。 屬性名稱和字符串值必須用雙引號(hào)引起來(lái)。
example.json
// ? 有效的 JSON(屬性名稱和值用雙引號(hào)引起來(lái))
{
"name": "Alice",
"age": 30
}確保你沒(méi)有尾隨逗號(hào)
在數(shù)組的最后一個(gè)元素或最后一個(gè)鍵值對(duì)之后有尾隨逗號(hào)會(huì)使我們的 JSON 無(wú)效。
example.json
// ?? 無(wú)效的 JSON(最后一個(gè)屬性后的尾隨逗號(hào))
{
"name": "Alice",
"age": 30, ??? 這個(gè)逗號(hào)使它無(wú)效 JSON
}
請(qǐng)注意,在 age 屬性之后有一個(gè)尾隨逗號(hào)。
這會(huì)使 JSON 無(wú)效,因?yàn)椴辉试S使用尾隨逗號(hào)。
要解決該錯(cuò)誤,請(qǐng)確保刪除所有結(jié)尾的逗號(hào)。
example.json
// ? 有效的 JSON(沒(méi)有尾隨逗號(hào))
{
"name": "Alice",
"age": 30
}發(fā)出 HTTP 請(qǐng)求時(shí)得到空響應(yīng)
如果我們?cè)诎l(fā)出 API 請(qǐng)求時(shí)遇到錯(cuò)誤,請(qǐng)確保響應(yīng)在解析之前具有 application/json 內(nèi)容類型標(biāo)頭。
import requests
def make_request():
response = requests.delete('https://example.com/api/users/2')
print('response: ???', response) # response: ??? <Response [204]>
print('response.text: ???', response.text) # response.text: ??? ""
# response.status_code: ??? 204
print('response.status_code: ???', response.status_code)
print('response.headers: ???', response.headers)
if (response.status_code != 204
and 'content-type' in response.headers
and 'application/json' in response.headers['content-type']):
parsed = response.json()
print('? parsed response: ???', parsed)
else:
# ??? this runs
print('?? conditions not met')
make_request()該示例使用 requests 包并發(fā)出 HTTP DELETE 請(qǐng)求,該請(qǐng)求返回 204 狀態(tài)(無(wú)內(nèi)容)。
嘗試像解析 JSON 一樣解析空響應(yīng)會(huì)引發(fā) JSONDecodeError,因此我們必須檢查:
- 響應(yīng)狀態(tài)不是 204(無(wú)內(nèi)容)。
- 響應(yīng)頭字典有一個(gè)內(nèi)容類型鍵。
- 內(nèi)容類型鍵的值為
application/json。
這樣我們就可以確定服務(wù)器在嘗試使用 reponse.json() 方法(如果使用請(qǐng)求)或 json.loads(my_json_str) 解析它之前向我們發(fā)送了一個(gè)有效的 JSON 響應(yīng)。
確保 API 不會(huì)以不正確的 Content-Type 響應(yīng)
如果服務(wù)器向我們發(fā)送了一個(gè)空響應(yīng)或響應(yīng)不是 application/json 類型,我們將收到 JSONDecodeError。
我們不能嘗試像解析 JSON 一樣解析 text/html 或 XML 響應(yīng)(或空響應(yīng))。
嘗試讀取一個(gè)空的 JSON 文件或錯(cuò)誤地讀取一個(gè) JSON 文件
該錯(cuò)誤通常是在以下情況下引起的:
- 試圖錯(cuò)誤地讀取 JSON 文件。
- 嘗試讀取一個(gè)空的 JSON 文件。
- 嘗試讀取包含無(wú)效 JSON 的 JSON 文件。
我們可以使用 json.load() 方法將 JSON 文件反序列化為 Python 對(duì)象。
import json
file_name = 'example.json'
with open(file_name, 'r', encoding='utf-8') as f:
my_data = json.load(f) # ??? 使用 load() 解析 JSON
print(my_data) # ??? {'name': 'Alice', 'age': 30}該示例假定在同一目錄中有一個(gè)名為 example.json 的文件。
example.json
{"name": "Alice", "age": 30}確保我們正在讀取的文件不為空,因?yàn)檫@通常會(huì)導(dǎo)致錯(cuò)誤。
使用 try/except 語(yǔ)句來(lái)處理潛在的錯(cuò)誤
如果我們的文件可能包含無(wú)效的 JSON,請(qǐng)使用 try/except 語(yǔ)句來(lái)處理錯(cuò)誤。
假設(shè)我們有以下 JSON 文件。
example.json
{
"name": "Alice",
'age': 30
}
請(qǐng)注意,age 屬性是單引號(hào)的,這使得 JSON 無(wú)效。
下面是我們?nèi)绾问褂?try/except 語(yǔ)句來(lái)處理錯(cuò)誤。
import json
file_name = 'example.json'
with open(file_name, 'r', encoding='utf-8') as f:
try:
my_data = json.load(f) # ??? 使用 load() 解析 JSON
print(my_data)
except BaseException as e:
print('The file contains invalid JSON')我們嘗試從文件中解析 JSON 數(shù)據(jù),但文件包含無(wú)效的 JSON,因此引發(fā)異常,然后在 except 塊中處理。
確保不將文件路徑傳遞給 json.loads()
錯(cuò)誤的另一個(gè)常見(jiàn)原因是在嘗試從 JSON 文件讀取時(shí)將文件路徑傳遞給 json.loads() 方法。
import json
file_name = 'example.json'
with open(file_name, 'r', encoding='utf-8') as f:
# ?? json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
my_data = json.loads(file_name) # ??? incorrectly passed file path
print(my_data) # ??? {'name': 'Alice', 'age': 30}json.load 方法用于將文件反序列化為 Python 對(duì)象,而 json.loads 方法用于將 JSON 字符串反序列化為 Python 對(duì)象。
import json
file_name = 'example.json'
with open(file_name, 'r', encoding='utf-8') as f:
my_data = json.load(f) # ? 將文件對(duì)象傳遞給 json.load()
print(my_data) # ??? {'name': 'Alice', 'age': 30}
json.load()方法需要一個(gè)包含實(shí)現(xiàn).read()方法的 JSON 文檔的文本文件或二進(jìn)制文件。
使用 json.loads() 手動(dòng)調(diào)用 read() 方法
或者,我們可以手動(dòng)調(diào)用文件對(duì)象的 read() 方法并使用 json.loads() 方法。
import json
file_name = 'example.json'
with open(file_name, 'r', encoding='utf-8') as f:
# ??? 確保調(diào)用 read()
my_data = json.loads(f.read())
print(my_data) # ??? {'name': 'Alice', 'age': 30}
print(type(my_data)) # ??? <class 'dict'>上面的示例實(shí)現(xiàn)了相同的結(jié)果,但是我們沒(méi)有依賴 json.load() 方法為我們調(diào)用文件對(duì)象上的 read() ,而是手動(dòng)執(zhí)行它并使用 json.loads() 方法。
json.loads() 方法基本上幫助我們從 JSON 字符串加載 Python 本機(jī)對(duì)象(例如字典或列表)。
在使用 json.loads() 之前嘗試讓你的 JSON 有效
如果我們需要在使用 json.loads() 方法之前使您的 JSON 有效,我們可以嘗試使用 str.replace() 方法。
下面是一個(gè)示例 JSON 文件,其中包含使 JSON 無(wú)效的單引號(hào)屬性。
example.json
{
"name": "Alice",
'age': 30
}下面是我們?nèi)绾问褂?str.replace() 方法將字符串中的單引號(hào)替換為雙引號(hào)。
import json
file_name = 'example.json'
with open(file_name, 'r', encoding='utf-8', errors='ignore') as f:
a_str = f.read()
# {
# "name": "Alice",
# 'age': 30 ??? note single quotes
# }
print(a_str)
# ? 用雙引號(hào)替換單引號(hào)
valid_json = a_str.replace("'", '"')
result = json.loads(valid_json)
print(result) # {'name': 'Alice', 'age': 30}
print(result['name']) # Alice
print(result['age']) # 30str.replace 方法返回字符串的副本,其中所有出現(xiàn)的子字符串都被提供的替換項(xiàng)替換。
該方法采用以下參數(shù):
- old 字符串中我們要替換的子串
- new 替換每次出現(xiàn)的 old
- count 僅替換第一個(gè) count 出現(xiàn)(可選)
我們使用 replace() 方法將字符串中所有出現(xiàn)的單引號(hào)替換為雙引號(hào)。
這使得 JSON 有效,因此我們可以安全地使用 json.loads() 方法。
JSONEncoder 類默認(rèn)支持以下對(duì)象和類型的轉(zhuǎn)換。
| Python | JSON |
|---|---|
| Python | JSON |
| dict | object |
| list, tuple | array |
| str | string |
| int、float、int 和 float 派生枚舉 | number |
| True | true |
| False | false |
| None | null |
通常導(dǎo)致錯(cuò)誤的事情
最常見(jiàn)的錯(cuò)誤原因是:
- 嘗試解析無(wú)效的 JSON 值(例如單引號(hào)或尾隨逗號(hào))。
- 從遠(yuǎn)程服務(wù)器(例如 204 或 404)獲取空響應(yīng)并嘗試將其作為 JSON 進(jìn)行解析。
- 嘗試像解析 JSON 一樣解析具有不同內(nèi)容類型(例如文本/html)的響應(yīng)。
- 嘗試錯(cuò)誤地讀取 JSON 文件或嘗試解析空 JSON 文件的內(nèi)容。
總結(jié)
Python“json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0) ”發(fā)生在我們?cè)噲D解析一些無(wú)效的 JSON 時(shí)。
要解決該錯(cuò)誤,需要確保響應(yīng)或文件不為空或在解析前有條件地檢查內(nèi)容類型。
到此這篇關(guān)于Python 中JSONDecodeError: Expecting value: line 1 column 1 (char 0)錯(cuò)誤的文章就介紹到這了,更多相關(guān)Python JSONDecodeError內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Win10下安裝CUDA11.0+CUDNN8.0+tensorflow-gpu2.4.1+pytorch1.7.0+p
這篇文章主要介紹了Win10下安裝CUDA11.0+CUDNN8.0+tensorflow-gpu2.4.1+pytorch1.7.0+paddlepaddle-gpu2.0.0,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03
Python并發(fā)請(qǐng)求下限制QPS(每秒查詢率)的實(shí)現(xiàn)代碼
這篇文章主要介紹了Python并發(fā)請(qǐng)求下限制QPS(每秒查詢率)實(shí)現(xiàn)方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-06-06
Python scipy實(shí)現(xiàn)差分進(jìn)化算法
差分進(jìn)化算法是廣義的遺傳算法的一種,核心思想是變異,這篇文章主要為大家介紹的則是著名的scipy庫(kù)中對(duì)差分進(jìn)化算法的實(shí)現(xiàn),希望對(duì)大家有所幫助2023-08-08
python基于pyDes庫(kù)實(shí)現(xiàn)des加密的方法
這篇文章主要介紹了python基于pyDes庫(kù)實(shí)現(xiàn)des加密的方法,結(jié)合實(shí)例形式較為詳細(xì)的分析了pyDes庫(kù)的下載、安裝及使用pyDes庫(kù)進(jìn)行加密的相關(guān)操作技巧,需要的朋友可以參考下2017-04-04

