iT邦幫忙

2021 iThome 鐵人賽

DAY 20
1
Software Development

從 JavaScript 角度學 Python系列 第 20

從 JavaScript 角度學 Python(20) - CSV

前言

前一章節簡單的聊了一下 JSON 之後,接下來我想額外補充一個關於 CSV 檔案處理的部分,而 CSV 通常在批次匯入的時候會很常看到,所以就特別拉一篇來聊聊。

who is CSV

通常看到 CSV 檔案的時候,大多人會覺得它是一個 Excel 或是 Google 試算表也不爲過,畢竟通常我們開啟 CSV 就是使用這幾種軟體去打開,我以前還以為 CSV 就是 Excel,還傻傻的問說 CSV 檔該怎麼打開。

應該是我太笨了吧?對吧?還是你也跟我一樣一開始以為 CSV 只是單純的 Excel 格式的一種呢?下面留言給我吧,讓我知道我不孤單。

https://ithelp.ithome.com.tw/upload/images/20210920/20119486NQyKJG1B8z.png

好,那麼什麼是 CSV 呢?CSV 是 Comma-Separated Values 的縮寫(我破英文覺得難唸),中文名稱是「逗號分隔值」,顧名思義就是使用逗號去做分隔每一個值的,通常第一排會是欄位名稱:

name,title,url
ray,Welcome.Web.World,https://hsiangfeng.github.io/

因此其實你使用 .txt 來撰寫也是可以達到相同效果,畢竟 CSV 就是一個純文字的檔案,因此你可以嘗試建立一個純文字檔案,然後寫入下方內容:

name,title,url
ray,Welcome.Web.World,https://hsiangfeng.github.io/

接下來存檔!再將副檔名改成 .csv,在去打開,你會發現是可以正常運作的,是不是超簡單的~

https://ithelp.ithome.com.tw/upload/images/20210920/201194866YOcFClnCD.png

因此如果你有使用一些批量匯入的服務,你也可以發現大多都是支援 .csv 與 .txt 哩~

那麼為什麼要特別講到 CSV 呢?就如同前面所言,許多系統都會支援 .csv 批次匯入,甚至你也可以看到一些爬蟲爬完資料之後就轉換成 CSV 格式,然後再上傳到自己的分析系統,所以好 CSV 不了解一下怎麼在 Python 中如何使用嗎?

https://ithelp.ithome.com.tw/upload/images/20210920/20119486ZjB3Gm7QBR.png

讀取 CSV

那麼首先我們先學如何讀取 CSV 當作起手式,因此我這邊有準備有一個簡易版的 .csv 檔,分別欄位是名字、標題與網址:

name,title,url
ray,Welcome.Web.World,https://hsiangfeng.github.io/
ray,第-13-屆-iT邦幫忙鐵人賽,https://hsiangfeng.github.io/tags/第-13-屆-iT邦幫忙鐵人賽/

蛤?你問我範例的 .csv 哪裡下載?我剛剛不是已經教你怎麼建立 csv 了嗎?

https://ithelp.ithome.com.tw/upload/images/20210920/20119486TGmSeJ7odS.png

簡單來講,你先建立一個 .txt 的文字檔案,然後填入我上面給的內容,再將副檔名改成 .csv 就可以囉。

那麼當你建立好後使用 Excel 或是 Google 試算表打開會像這樣子呈現:

https://ithelp.ithome.com.tw/upload/images/20210920/201194862wuiK6OdIF.png

題外話一下你可以嘗試將 .csv 檔案拖進 VSCode 中,這樣也可以打開來看的。

但是如果你覺得一推逗號很難看的話,也可以替 VSCode 安裝 Excel Viewer 套件來觀看 csv 檔:

https://ithelp.ithome.com.tw/upload/images/20210920/20119486H63bG7UIK9.png

(這邊也稍微讓我置入性行銷一下,如果你想知道更多套件的話,可以閱讀這一篇 Visual Studio Code(VSCode) 必備實用套件。)

稍微扯遠了,讓我們回到 Python 中,接下來由於要讀取 CSV 檔案所以我們必須引入 CSV 模組,概念就跟使用 JSON 的時候一樣。

但是在引入之前我們可以先嘗試打開 .csv 檔案:

f = open('example.csv', 'r')
read = f.read()
f.close()
print(read)

基本上我們可以知道是可以正常運作的,但是如果你想要取值的話就會無法正常取值:

print(read['name']) # TypeError: string indices must be integers

畢竟概念就跟 JSON 章節的狀況是一樣的。

哦!順道提一下,在 Node.js 開發時也是需要引入 CSV 相關套件的,例如...csv-parse

var csvParse = require('csv-parse');
...

因此我們就會需要借助 CSV 模組的方法來幫我們正確的讀取轉換 .csv 資料,而讀取的函式是 reader(),如果想要正確的取出資料的話,就必須使用 for in 迴圈。

疑?為什麼要用 for in 呢?主要原因是 CSV 模組在處理時,它會將逗號結尾最後一個元素的作為一個陣列的終點,什麼意思呢?例如剛剛的範例:

name,title,url
ray,Welcome.Web.World,https://hsiangfeng.github.io/
ray,第-13-屆-iT邦幫忙鐵人賽,https://hsiangfeng.github.io/tags/第-13-屆-iT邦幫忙鐵人賽/

雖然我前面是這樣講,但是實際上你輸出的話會看到一串詭異的東西:

<_csv.reader object at 0x1021b7660>

https://ithelp.ithome.com.tw/upload/images/20210920/20119486CYPAs48EMM.png

所以我覺得你可以把 CSV 處理後的 .csv 檔案資料它想像成這樣子:

[
  ['name', 'title', 'url'],
  ['ray', 'Welcome.Web.World', 'https://hsiangfeng.github.io/'],
  ['ray', '第-13-屆-iT邦幫忙鐵人賽', 'https://hsiangfeng.github.io/tags/第-13-屆-iT邦幫忙鐵人賽/']
]

因此我們就會需要使用 for in 將剛剛讀取出來的 .csv 資料輸出:

import csv
csvfile = open('example.csv', 'r')

rows = csv.reader(csvfile)
for row in rows:
  print(row)

https://ithelp.ithome.com.tw/upload/images/20210920/20119486jC4STHMIbt.png

是不是覺得超簡單呢?

https://ithelp.ithome.com.tw/upload/images/20210920/20119486TpwCv80KLc.png

寫入 CSV

那麼有讀取的話,想當然就一定會有寫入的行為,所以接下來就會來試著將資料寫入到 .csv 中。

那麼 CSV 之所以好用還有一個原因是很接近一個陣列形式,前面我們有大概舉例它的形式類似以下:

[
  ['name', 'title', 'url'],
  ['ray', 'Welcome.Web.World', 'https://hsiangfeng.github.io/'],
  ['ray', '第-13-屆-iT邦幫忙鐵人賽', 'https://hsiangfeng.github.io/tags/第-13-屆-iT邦幫忙鐵人賽/']
]

因此整體概念與串列非常類似,但是絕對不是叫你用 append() 去寫入 .csv,這邊你依然必須是使用 CSV 模組的方法去寫入,因此起手式必須先建立寫入的行為也就是 writer,你必須告知 CSV 模組預計要寫入到哪個檔案:

import csv
csvfile = open('example.csv', 'r')

csvWriter = csv.writer(csvfile)

準備好起手式之後,接下來只需要使用 writerow 方法就可以開始寫入囉:

import csv
csvfile = open('example.csv', 'w')

csvWriter = csv.writer(csvfile)
csvWriter.writerow(['ray','粉絲專頁','https://www.facebook.com/HsiangFengWeb'])

接下來你再去打開這個檔案就可以看到剛剛的內容被成功寫入了:

name,title,url
ray,Welcome.Web.World,https://hsiangfeng.github.io/
ray,第-13-屆-iT邦幫忙鐵人賽,https://hsiangfeng.github.io/tags/第-13-屆-iT邦幫忙鐵人賽/
ray,粉絲專頁,https://www.facebook.com/HsiangFengWeb

如果你期望寫入多筆資料的話,就會需要搭配迴圈:

import csv
csvfile = open('example.csv', 'w')

csvWriter = csv.writer(csvfile)

data = [
  ['ray', 'Welcome.Web.World', 'https://hsiangfeng.github.io/'],
  ['ray', '第-13-屆-iT邦幫忙鐵人賽', 'https://hsiangfeng.github.io/tags/第-13-屆-iT邦幫忙鐵人賽/'],
  ['ray','粉絲專頁','https://www.facebook.com/HsiangFengWeb']
]

for row in data:
  csvWriter.writerow(row)

這邊請務必注意 open 的模式,如果你期望是開啟檔案後從檔案結尾寫入,記得要將模式改成 a 唷。

作者的話

今天嘗試製作紹興醉雞後,發現味道與花雕真的有一點差異,整體來講花雕比較香,但是紹興酒味比較濃(我的錯覺?),但是兩者吃起來感覺差異不大,但是還不錯吃就是了,講到紹興也讓我想到高雄旗山有一個很有名的炒飯叫做紹興炒飯,這間的炒飯真的吃一次後就會很難忘記,推薦有機會去旗山玩的人可以吃看看。

關於兔兔們

兔法無邊


上一篇
從 JavaScript 角度學 Python(19) - JSON
下一篇
從 JavaScript 角度學 Python(21) - Requests
系列文
從 JavaScript 角度學 Python31

尚未有邦友留言

立即登入留言