文件操作
引言
爬蟲爬取的一切內容都是在內存進行的,這樣會有什么問題嗎?如果一旦短電或著發生意外電腦關機了那么你的工作成果將瞬間消失。所以,我們還缺少數據在本地文件系統進行持久化的能力,簡單的來說就是文件讀寫操作。文件讀寫操作在爬蟲中是必不可缺少的一部分。
文件打開
Python中內置了一個open()方法,用于對文件讀寫操作。使用open()方法操作文件可以分三步,一是打開文件,二是操作文件,三是關閉文件。
文件句柄/文件描述符
open()方法返回值是一個file對象,可以將它賦值給一個變量,這個變量就是所謂的文件句柄
file對象
可以調用read()和write()方法,對打開的文件進行讀寫操作
open方法的語法
f = open(fliename,mode)
filename
一個包含了你要訪問的文件名稱的字符串值,通常是文件路徑。文件路徑作用:定位到指定文件
mode
打開文件的模式,默認是只讀r
文件打開的模式
常規文件打開模式操作示例
b模式:
二進制模式,通常用于讀取圖片、視頻等二進制文件,注意,它在讀寫的時侯以bytes類型讀寫的,因此獲得的是bytes對象而不是字符串在這個讀寫過程中,需要自己指定編碼格式。在使用帶b的模式一定要注意傳入的數據類型,確保為bytes類型。
+模式:
對于w+模式,在讀寫之前都會清空文件的內容,建議不要使用。
對于a+模式,永遠只能在文件末尾寫入,有局限性。
對于r+模式,也就是讀寫模式,配合seek()和tell()方法可以實現更多操作
編碼問題
要讀取非utf-8文件,需要給open()函數傳入encoding參數,例如,讀取GBK編碼的文件。
遇到一些編碼不規范的文件,可能會拋出UnicodeDecodeError異常這表示在文件中可能摻雜了一些非法編碼的。遇到這種情況可以提供errors='ignore'參數,表示如果遇到編碼錯誤后如何處理。
文件對象操作
每當我們用open()方法打開文件時,將返回文件對象。這個對象內置了很多操作方法。
f.read(size)#size讀取數據的個數
讀取一定大小的數據,然后作為字符串或字節對象返回,size是一個可選的數字類型的參數,用于指定讀取的數據量。當size被忽略了或者為負值,那么該文件的所有內容都將被讀取并且返回。
注意:如果文件體積較大,建議不要使用read()方法一次性讀入內存,而是read(512)一點一點的讀。
f.readline()
從文件一行讀取n內容。換行'\n'。如果返回一個空字符串,說明已經讀取到最后一行。這種方法通常是讀一行處理一行,并且不能回頭讀過的行不能在讀了。
f.readlines()
件文件中所有的行,一行一行全部讀入一個列表內,按順序一個一個全部讀入列表內,并返回這個列表。readlines方法一次性將文件全部讀入內存,所以也存在一定的問題。但是它有個好處,每行都保存在列表里,可以隨意存取。
fp = open('./text.txt','r')
text = for.read(10) #讀取指定字節的數據
text_line = fp.readline() #一次讀取一行數據
text_lines = fp.readlines() #讀取多行數據返回一個列表
print(text_lines)
fq.close()
f.seek()
如果需要改變文件指針的位置,可以使用f.seek(offset,from_what)方法。seek()經常和tell()方法配合使用。
from_what
如果是0表示從文件開頭計算
如果是1表示表示從文件讀寫指針的當前位置開始計算
2表示從文件結尾開始計算,默認是0
offset:表示偏移量
seek(x,0):從文件首行首字符開始移動x個字節
seek(x,1):表示從當前位置往后移動x個字節
seek(-x,2):表示從文件的末尾往前移動x個字節
fp=open('./text.txt','r')
fp.seek(9,0)
text=fp.read(5)
print(text)
f.tell()
返回文件讀寫指針當前所處的位置,它是從文件開頭開始算起的字節數。一定要注意是字節數,而不是字符數。
fp=open('./text.txt','r')
print(fp.tell)
fp.close()
f.write()
將字符串或bytes類型的數據寫入文件內。write()動作可以多次重復進行,其實都是在內存中操作,并不會立刻寫入硬盤,直到執行close()方法后,才會將所有的的寫入操作反映到硬盤上,在這個過程中,如果想將內存中修改,立刻保存到硬盤上,可以使用f.flush()方法。
fp=open('./text.txt','w')
fp.write('hello')
fp.close() #清空后寫入
fp=open('./text.txt','a')
fp.write('hello')
fp.close() #追加