1. 程式人生 > >Class 15 - 1 數據存儲——文件存儲

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

熱門話題 gen color 簡化 www. ram sts 爬取 答案

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

一、TXT文本存儲

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

      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,這樣在每次寫入文本時不會清空源文件, 而是在文件末尾寫入新的內容,這是一種文件打開方式。

      • 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)

二、Json文件存儲

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))

三、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 文件的方法。

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