iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 3
0
AI & Data

Scrapy爬蟲與資料處理30天筆記系列 第 3

[Day 03] 檔案讀取/寫入

嗨,第三天,來說明一下讀取/寫入檔案,並說明不同的模式(mode)。

下面為讀取檔案的程式碼:

with open('textFileName.txt', 'r') as f:
    data = f.read()

說明一下open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True),這個函數我們常用的參數為file, modeencoding

  • file: 讀取的檔案路徑
  • encoding: 返回的數據採用何種編碼
  • mode 如下表格:
Mode 描述
+ 打開一個文件進行更新(可讀可寫)
r 以只讀方式打開文件
r+ 打開一個文件用於讀寫
w 打開一個文件只用於寫入,如果該文件已存在則打開文件,並從開頭開始編輯,原有內容會被刪除。如果該文件不存在,創建新文件。
w+ 打開一個文件用於讀寫。如果該文件已存在則打開文件,並從開頭開始編輯,原有內容會被刪除。如果該文件不存在,創建新文件。
a 打開一個文件用於追加。如果該文件已存在,新的內容將會被寫入到已有內容之後。如果該文件不存在,創建新文件進行寫入。
a+ 打開一個文件用於讀寫。如果該文件已存在,文件指針將會放在文件的結尾。文件打開時會是追加模式。如果該文件不存在,創建新文件用於讀寫。
ab+ 以二進制格式打開一個文件用於追加。

以上為常用的讀寫檔案模式,要記下來~


那我們就來實作一下吧!

  • 先建立一個myTxtFIle.txt文字檔案,並寫下兩行以上的內容,例如:
hello world! 
I am plusone.

看看下面兩個讀檔的差別吧?能夠用for迴圈去讀取檔案的每一行,也可以用read()得到所有檔案內容。

with open('myTxtFIle.txt', 'r') as f:
    data = f.read()
    print(data)
    print('------------------')
    
with open('myTxtFIle.txt', 'r') as f:
    for line in f:
        print(line)
        print('------------------')

假設要寫入呢?使用帶有w模式的open()函數,若之前文件內容存在則清除並覆蓋掉:

with open('writeSomething.txt', 'w') as f:
    f.write('hello\n')
    f.write('world')

執行後,可以看到目錄下建立了一個writeSomething.txt檔案,內容為:

hello
world

假設今天是要在文件後面添加內容,而不像上一個每次執行都覆蓋掉原本的內容,則是用a就行了:

with open('appendSomething.txt', 'a') as f:
    f.write('hello\n')
    f.write('world')
  • 能夠寫入為兩行是因為在hello後面加了\n,若沒有\n則會是helloworld哦!

在Unix和Windows中是不一樣的分別是\n\r\n。默認情況下,Python會統一模式處理換行符。在讀取檔案的時候,Python會識別所有換行符並將其轉換為單個\n字符。在輸出時會將換行符\n轉換為系統默認的換行符。
如果你不希望這種默認的處理方式,可以給open()函數傳入參數newline=''

with語法會給被使用到的文件創建了一個上下文環境,且區塊結束後會自動關閉,若不使用with,就必須記得手動關閉文件:

f = open('someTextFile.txt', 'rt')
data = f.read()
f.close()

文件的讀/寫會默認使用系統編碼,可以使用sys.getdefaultencoding()來得到。
在大多數都是utf-8編碼。也可以傳遞encoding參數給open()函數:

with open('textFile.txt', 'rt', encoding='latin-1') as f:
    ...

再來,要提到一個可能會發生的錯誤:
UnicodeDecodeError: 'ascii' codec can't decode byte ____ in position __: ordinal not in range(128)

這表示指定的編碼不正確。先確認編碼為何,如果編碼錯誤還是在的話,你可以給open()函數傳遞errors='replace'errors='ignore'參數來處理。
不過這就跟try,except一樣,不是一個良好的解決方式,所以說還是好好確認編碼是什麼吧!

觀樂的時光總是過得特別快,第三天說明了with open的操作,之後也會說如何操作jsoncsv檔案。還有我如何在爬資料的時候用with opendebug(嗎)XD ,也歡迎大家提供更好的做法~


上一篇
[Day 02] 用Virtual Environment吧!
下一篇
[Day 04] CSV 讀寫操作
系列文
Scrapy爬蟲與資料處理30天筆記30

尚未有邦友留言

立即登入留言