Class 15 - 1 數據存儲——文件存儲

保存的形式能夠多種多樣,最簡單的形式是 接保存爲文本文件,如 TXT、JSON、CSV等。還能夠保存到數據庫中,如關係型數據庫 MySQL ,非關係型數據庫 MongoDB、Redis等。javascript

1、TXT文本存儲 html

  1. 基本實例:
    • 能夠用 requests 將網頁源代碼獲取下來,而後使用 pyquery 解析庫解析,接下來將提取的標題、 回答者、 回答保存到文本,代碼:java

      import requests
      from pyquery import PyQuery as pq
      url = 'https://www.zhihu.com/explore'
      headers = {
          'User-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36'
      }
      html = requests.get(url,headers =headers).text
      doc = pq(html)
      items = doc('.explore-tab .feed-item').items()
      for item in items:
          question = item.find('h2').text()
          author = item.find('.author-link-line').text()
          answers = pq(item.find('.content').html()).text()
          file = open('explore.txt', 'a', encoding='utf-8')
          file.write('\n'.join([question, author, answers]))
          file.write('\n'+'='*50+'\n')
          file.close()

      用 requests 提取知乎的"發現"頁面,而後將熱門話題的問題、回答者、答案全文提取出來,而後利用 Python 提供的open()方法打開一個文本文件,獲取一個文件操做對象,這裏賦值爲 file,接着利用 file 對 象的 write()方法將提取的內容寫入文件,最後調用 ιlose()方法將其關閉,這樣抓取的內容便可成功 寫入文本中了。數據庫

  2. 打開方式
    • open()方法的第二個參數設置成了 a,這樣在每次寫入文本時不會清空源文件, 而是在文件末尾寫入新的內容,這是一種文件打開方式。 json

      • r:以只讀方式打開文件。 文件的指針將會放在文件的開頭。 這是默認模式。數組

      • rb:以二進制只讀方式打開一個文件。 文件指針將會放在文件的開頭。
      • r+:以讀寫方式打開一個文件, 文件指針將會放在文件的開頭。 
      • rb+:以二進制讀寫方式打開一個文件。 文件指針將會放在文件的開頭。
      • w:以寫入方式打開一個文件。 若是該文件已存在,則將其覆蓋。 若是該文件不存在,則建立新文件。 
      • wb:以二進制寫入方式打開一個文件。 若是該文件已存在,則將其覆蓋。 若是該文件不存 在, 則建立新文件
      • w+:以讀寫方式打開一個文件。 若是該文件已存在,則將其覆蓋。 若是該文件不存在,則創 建新文件
      • wb+:以二進制讀寫格式打開一個文件。 若是該文件已存在, 則將其覆蓋。 若是該文件不存 在, 則建立新文件。
      • a: 以追加方式打開一個文件。 若是該文件已存在,文件指針將會放在文件結尾, 若是該文件不存在, 則建立新文件來寫入。
      • ab:以二進制追加方式打開一個文件。 若是該文件已存在,則文件指針將會放在文件結尾,若是該文件不存在,則建立新文件來寫入
      • a+:以讀寫方式打開一個文件。 若是該文件已存在,文件指針將會放在文件的結尾。 文件打 開時會是追加模式。 若是文件不存在,則建立新文件來讀寫。
      • ab+:以二進制追加方式打開一個文件。 若是該文件已存在,則文件指針將會放在文件結尾。 若是該文件不存在,則建立新文件用於讀寫
  3. 簡化寫法
    • 使用 with as 語法。在 with 控制塊結束時,文件會自動關閉,不須要再調用 close()方法。示例:
        with open('explore.txt', 'a', encoding='utf-8') as file:
              file.write('\n'.jason([question,author,answers]))
              file.write('\n'+'='*50+'\n')

       若是想保存時將原文清空,那麼能夠將第二個參數改寫爲 w,示例:數據結構

         with open('explore.txt', 'w', encoding='utf-8') as file:
              file.write('\n'.jason([question,author,answers]))
              file.write('\n'+'='*50+'\n')

2、Json文件存儲ide

JSON,全稱爲 JavaScript Object Notation, 是 JavaScript對象標記, 經過對象和數組的組合來表示數據,構造簡潔但結構化程度很是高,是一種輕量級的數據交換格式。函數

  1. 對象和數組
    • 在 JavaScript語言中,一切都是對象。 所以,任何支持的類型均可以經過 JSON來表示,如:字符串、數字、對象、數組等,對象和數組是比較特殊且經常使用的兩種類型編碼

      • 對象:在 JavaScript 中是使用花括號{}包裹起來的內容,數據結構爲{key1: value1, key2: value2,… }的鍵值對結構。 在面向對象的語言中, key 爲對象的屬性, value 爲對應的值。 鍵名可使用整數和字符串來表示。 值的類型能夠是任意類型。 
      • 數組:數組在 JavaScript 中是方括號[]包裹起來的內容,數據結構爲["java","javascript","vb",.... ]的索引結構。在JavaScript 中, 數組是一種比較特殊的數據類型,也能夠像對象那樣使用鍵值對,但仍是索引用得多。 一樣,值的類型能夠是任意類型。
        • 因此,一個JSON對象能夠寫成以下形式:
          [{
              "name": "Bob",
              "gender": "male",
              "birthday": "1992-10-18",},
              {"name": "Snlina",
               "gender": "female",
               "birthday": "1995-10-18"
          }]

          由中括號包圍的就至關於列表類型,列表中的每一個元素能夠是任意類型,這個示例中它是字典類型,由大括號包圍。
          JSON 能夠由以上兩種形式自由組合而成,能夠無限次嵌套,結構清晰,是數據交換的極佳方式。

  2. 讀取JSON
    • 能夠調用 JSON 庫 的 loads()方法將 JSON 文本字符串轉爲 JSON對象,能夠經過 dumps()方法將 JSON 對象轉爲文本字符串。
      例:一段 JSON 形式的字符串,是 str 類型,能夠用 Python 將其轉換爲可操做的數據結構——列表或字典:

      import json
      str = '''
          [{ "name":"Bob",
               "gender":"male",
               "birthday": "1992-10-18"
               },{
               "name": "Selina",
              "gender":"female",
              "birthday": "1995-10-18"
      }]
      '''
      print(type(str))
      data = json.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'>
      View Code

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

      針對列表,能夠用索引來獲取對應的內容。 如,想取第一個元素裏的 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 json
      str = '''
          [{ 'name':'Bob',
               'gender':'male',
               'birthday': '1992-10-18'
               },{
               'name': 'Selina',
              'gender':'female',
              'birthday':'1995-10-18'
      }]
      '''
      data = json.loads(str)
      輸出:
      json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 2 column 8 (char 8)
      View Code

      出現 JSON解析錯誤提示。注意:JSON 字符串的表示須要用雙引號,不然 loads()方法會解析失敗

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

      import json
      with open('data.json','r') as file:
          str = file.read()
          data = json.loads(str)
          print(data) 
  3. 輸出JSON

    • 能夠調用 dumps()方法將 JSON 對象轉化爲字符串。 例:將例中的列表從新寫入文本:

      import json
      data = '''
          [{
          "name": "Bob",
          "gender": "male",
          "birthday": "1992-10-18"
      }]
      '''
      with open('data.json','a',encoding='utf-8') as f:
          f.write(json.dumps(data))

      利用 dumps()方法,能夠將 JSON 對象轉爲字符串,而後再調用文件的 write()方法寫入文本

    •  

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

      with open('data.json','a',encoding='utf-8') as f:
          f.write(json.dumps(data,indent=2))

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

    • 若是 JSON 中包含中文字符,須要指定參數 ensure_ascii 爲 False,還要規定文件輸出的編碼:

      with open('data.json','w',encoding='utf-8') as f:
          f.write(json.dumps(data,indent=2,ensure_ascii= False))

3、CSV文件存儲    

  1. 寫入
    • import csv
      with open('data.csv','w') as csvfile:
          writer =csv.writer(csvfile)
          writer.writerow(['id','name','age'])
          writer.writerow(['10001','Mike',20])
          writer.writerow(['10002','Bob',22])
          writer.writerow(['10003','Jordan',21])

      首先打開 data.csv 文件,而後指定打開的模式爲 w(寫入),得到文件句柄,隨後調用 csv 庫 的 writer()方法初始化寫人對象,傳入該句柄,而後調用 writerow()方法傳入每行的數據便可完成寫入。

      寫人的文本默認以逗號分隔,調用一次 writerow()方法便可寫入一行數據
    • 若是想修改列與列之間的分隔符,能夠傳入 delimiter 參數,代碼以下:

      import csv
      with open('data.csv','w') as csvfile:
          writer =csv.writer(csvfile,delimiter='')
          --snip--

      裏在初始化寫入對象時傳入 delimiter 爲空格, 此時輸出結果的每一列就是以空格分隔

    • 也能夠調用 writerows()方法同時寫入多行, 此時參數須要爲二維列表,例:

      import csv
      with open('data.csv','w') as csvfile:
          writer =csv.writer(csvfile)
          writer.writerow(['id','name','age'])
          writer.writerow(['10001','Mike',20],['10002','Bob',22],['10003','Jordan',21])

      輸出內容相同。

    • 是通常狀況下,爬蟲爬取的都是結構化數據,通常會用字典來表示。在 CSV 庫中也提供了字典的寫入方式,示例:

      import csv
      with open('data.csv','w') as csvfile:
          filenames = ['id','name','age']
          writer = csv.DictWriter(csvfile,fieldnames=filenames)
          writer.writeheader()
          writer.writerow({'id':'10001','name':'Mike','age':20})
          writer.writerow({'id':'10002','name':'Bob','age':22})
          writer.writerow({'id':'10003','name':'Jordan','age':21})

      先定義 3 個字段,用 fieldnames 表示,再將其傳給 DictWriter 來初始化一個字典寫人對 象,接着調用 writeheader()方法先寫人頭信息,而後再調用 writerow()方法傳人相應字典。

    • 若是想追加寫人,能夠修改文件的打開模式,即將 open()函數的第二個參數改爲 a,示例:

      import csv
      with open('data.csv','a') as csvfile:
          filenames = ['id','name','age']
          writer = csv.DictWriter(csvfile,fieldnames=filenames)
          writer.writerow({'id':'10004','name':'Durant','age':22})
    • 若是要寫入中文內容,可能會遇到字符編碼的問題,此時須要給 open()參數指定編碼格式。 例如,再寫入一行包含中文的數據,代碼須要改寫:

      import csv
      with open('data.csv','a',encoding='utf-8') as csvfile:
          filenames = ['id','name','age']
          writer = csv.DictWriter(csvfile,fieldnames=filenames)
          writer.writerow({'id':'10005','name':'王偉','age':22})

      這裏須要給 open()函數指定編碼,不然可能發生編碼錯誤。

    • 若是接觸過 pandas 庫的話,能夠調用 DataFrame 對象的 to_csv()方法來將數據寫人 csv 文件中。

  2. 讀取

    • 一樣可使用 csv 庫來讀取 csv 文件。 如,將寫入的文件內容讀取出來,以下:

      import csv
      with open('data.csv','r',encoding='utf-8') as csvfile:
          reader =csv.reader(csvfile)
          for row in reader:
              print(row)

      這裏構造的是 Reader 對象,經過遍歷輸出了每行的內容,每一行都是一個列表形式。 注意, 若是 csv 文件中包含中文的話,還須要指定文件編碼。

    • 若是知道 pandas庫,能夠利用 read_csv()方法將數據從 csv 中讀取出來,如:

      import pandas as pd
      df=pd.read_csv('data.csv')
      print(df)

      在作數據分析的時候,此種方法用得比較多,也是一種比較方便地讀取 csv 文件的方法。

相關文章
相關標籤/搜索