【Python3網絡爬蟲開發實戰】5-數據存儲-1 文件存儲-2 JSON文件存儲

JSON,全稱爲JavaScript Object Notation, 也就是JavaScript對象標記,它經過對象和數組的組合來表示數據,構造簡潔可是結構化程度很是高,是一種輕量級的數據交換格式。本節中,咱們就來了解如何利用Python保存數據到JSON文件。javascript

1. 對象和數組

在JavaScript語言中,一切都是對象。所以,任何支持的類型均可以經過JSON來表示,例如字符串、數字、對象、數組等,可是對象和數組是比較特殊且經常使用的兩種類型,下面簡要介紹一下它們。html

  • 對象:它在JavaScript中是使用花括號{}包裹起來的內容,數據結構爲{key1:value1, key2:value2, ...}的鍵值對結構。在面向對象的語言中,key爲對象的屬性,value爲對應的值。鍵名可使用整數和字符串來表示。值的類型能夠是任意類型。
  • 數組:數組在JavaScript中是方括號[]包裹起來的內容,數據結構爲["java", "javascript", "vb", ...]的索引結構。在JavaScript中,數組是一種比較特殊的數據類型,它也能夠像對象那樣使用鍵值對,但仍是索引用得多。一樣,值的類型能夠是任意類型。

因此,一個JSON對象能夠寫爲以下形式:java

[{
    "name": "Bob",
    "gender": "male",
    "birthday": "1992-10-18"
}, {
     "name": "Selina",
    "gender": "female",
    "birthday": "1995-10-18"
}]
複製代碼

由中括號包圍的就至關於列表類型,列表中的每一個元素能夠是任意類型,這個示例中它是字典類型,由大括號包圍。數組

JSON能夠由以上兩種形式自由組合而成,能夠無限次嵌套,結構清晰,是數據交換的極佳方式。bash

2. 讀取JSON

Python爲咱們提供了簡單易用的庫來實現JSON文件的讀寫操做,咱們能夠調用庫的loads()方法將JSON文本字符串轉爲JSON對象,能夠經過dumps()方法將JSON對象轉爲文本字符串。微信

例如,這裏有一段JSON形式的字符串,它是str類型,咱們用Python將其轉換爲可操做的數據結構,如列表或字典:網絡

import 

str = ''' [{ "name": "Bob", "gender": "male", "birthday": "1992-10-18" }, { "name": "Selina", "gender": "female", "birthday": "1995-10-18" }] '''
print(type(str))
data = .loads(str)
print(data)
print(type(data))
複製代碼

運行結果以下:數據結構

<class 'str'>
[{'name': 'Bob', 'gender': 'male', 'birthday': '1992-10-18'}, {'name': 'Selina', 'gender': 'female', 'birthday': '1995-10-18'}]
<class 'list'>
複製代碼

這裏使用loads()方法將字符串轉爲JSON對象。因爲最外層是中括號,因此最終的類型是列表類型。ui

這樣一來,咱們就能夠用索引來獲取對應的內容了。例如,若是想取第一個元素裏的name屬性,就可使用以下方式:編碼

data[0]['name']
data[0].get('name')
複製代碼

獲得的結果都是:

Bob
複製代碼

經過中括號加0索引,能夠獲得第一個字典元素,而後再調用其鍵名便可獲得相應的鍵值。獲取鍵值時有兩種方式,一種是中括號加鍵名,另外一種是經過get()方法傳入鍵名。這裏推薦使用get()方法,這樣若是鍵名不存在,則不會報錯,會返回None。另外,get()方法還能夠傳入第二個參數(即默認值),示例以下:

data[0].get('age')
data[0].get('age', 25)
複製代碼

運行結果以下:

None
25
複製代碼

這裏咱們嘗試獲取年齡age,其實在原字典中該鍵名不存在,此時默認會返回None。若是傳入第二個參數(即默認值),那麼在不存在的狀況下返回該默認值。

值得注意的是,JSON的數據須要用雙引號來包圍,不能使用單引號。例如,若使用以下形式表示,則會出現錯誤:

import 

str = ''' [{ 'name': 'Bob', 'gender': 'male', 'birthday': '1992-10-18' }] '''
data = .loads(str)
複製代碼

運行結果以下:

.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 3 column 5 (char 8)
複製代碼

這裏會出現JSON解析錯誤的提示。這是由於這裏數據用單括號來包圍,請千萬注意JSON字符串的表示須要用雙引號,不然loads()方法會解析失敗。

若是從JSON文本中讀取內容,例如這裏有一個data.文本文件,其內容是剛纔定義的JSON字符串,咱們能夠先將文本文件內容讀出,而後再利用loads()方法轉化:

import 

with open('data.', 'r') as file:
    str = file.read()
    data = .loads(str)
    print(data)
複製代碼

運行結果以下:

[{'name': 'Bob', 'gender': 'male', 'birthday': '1992-10-18'}, {'name': 'Selina', 'gender': 'female', 'birthday': '1995-10-18'}]
複製代碼

3. 輸出JSON

另外,咱們還能夠調用dumps()方法將JSON對象轉化爲字符串。例如,將上例中的列表從新寫入文本:

import 

data = [{
    'name': 'Bob',
    'gender': 'male',
    'birthday': '1992-10-18'
}]
with open('data.', 'w') as file:
    file.write(.dumps(data))
複製代碼

利用dumps()方法,咱們能夠將JSON對象轉爲字符串,而後再調用文件的write()方法寫入文本,結果如圖5-2所示。

圖5-2 寫入結果

另外,若是想保存JSON的格式,能夠再加一個參數indent,表明縮進字符個數。示例以下:

with open('data.', 'w') as file:
    file.write(.dumps(data, indent=2))
複製代碼

此時寫入結果如圖5-3所示。

圖5-3 寫入結果

這樣獲得的內容會自動帶縮進,格式會更加清晰。

另外,若是JSON中包含中文字符,會怎麼樣呢?例如,咱們將以前的JSON的部分值改成中文,再用以前的方法寫入到文本:

import 

data = [{
    'name': '王偉',
    'gender': '男',
    'birthday': '1992-10-18'
}]
with open('data.', 'w') as file:
    file.write(.dumps(data, indent=2))
複製代碼

寫入結果如圖5-4所示。

圖5-4 寫入結果

能夠看到,中文字符都變成了Unicode字符,這並非咱們想要的結果。

爲了輸出中文,還須要指定參數ensure_asciiFalse,另外還要規定文件輸出的編碼:

with open('data.', 'w', encoding='utf-8') as file:
    file.write(.dumps(data, indent=2, ensure_ascii=False))
複製代碼

寫入結果如圖5-5所示。

圖5-5 寫入結果

能夠發現,這樣就能夠輸出JSON爲中文了。

本節中,咱們瞭解了用Python進行JSON文件讀寫的方法,後面作數據解析時常常會用到,建議熟練掌握。

本資源首發於崔慶才的我的博客靜覓: Python3網絡爬蟲開發實戰教程 | 靜覓

如想了解更多爬蟲資訊,請關注個人我的微信公衆號:進擊的Coder

weixin.qq.com/r/5zsjOyvEZ… (二維碼自動識別)

相關文章
相關標籤/搜索