前一章節簡單的聊了一下 JSON 之後,接下來我想額外補充一個關於 CSV 檔案處理的部分,而 CSV 通常在批次匯入的時候會很常看到,所以就特別拉一篇來聊聊。
通常看到 CSV 檔案的時候,大多人會覺得它是一個 Excel 或是 Google 試算表也不爲過,畢竟通常我們開啟 CSV 就是使用這幾種軟體去打開,我以前還以為 CSV 就是 Excel,還傻傻的問說 CSV 檔該怎麼打開。
應該是我太笨了吧?對吧?還是你也跟我一樣一開始以為 CSV 只是單純的 Excel 格式的一種呢?下面留言給我吧,讓我知道我不孤單。
好,那麼什麼是 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,在去打開,你會發現是可以正常運作的,是不是超簡單的~
因此如果你有使用一些批量匯入的服務,你也可以發現大多都是支援 .csv 與 .txt 哩~
那麼為什麼要特別講到 CSV 呢?就如同前面所言,許多系統都會支援 .csv 批次匯入,甚至你也可以看到一些爬蟲爬完資料之後就轉換成 CSV 格式,然後再上傳到自己的分析系統,所以好 CSV 不了解一下怎麼在 Python 中如何使用嗎?
那麼首先我們先學如何讀取 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 了嗎?
簡單來講,你先建立一個 .txt 的文字檔案,然後填入我上面給的內容,再將副檔名改成 .csv 就可以囉。
那麼當你建立好後使用 Excel 或是 Google 試算表打開會像這樣子呈現:
題外話一下你可以嘗試將 .csv 檔案拖進 VSCode 中,這樣也可以打開來看的。
但是如果你覺得一推逗號很難看的話,也可以替 VSCode 安裝 Excel Viewer 套件來觀看 csv 檔:
(這邊也稍微讓我置入性行銷一下,如果你想知道更多套件的話,可以閱讀這一篇 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>
所以我覺得你可以把 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)
是不是覺得超簡單呢?
那麼有讀取的話,想當然就一定會有寫入的行為,所以接下來就會來試著將資料寫入到 .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
唷。
今天嘗試製作紹興醉雞後,發現味道與花雕真的有一點差異,整體來講花雕比較香,但是紹興酒味比較濃(我的錯覺?),但是兩者吃起來感覺差異不大,但是還不錯吃就是了,講到紹興也讓我想到高雄旗山有一個很有名的炒飯叫做紹興炒飯,這間的炒飯真的吃一次後就會很難忘記,推薦有機會去旗山玩的人可以吃看看。