如何高效率地使用 Python 走訪資料夾中的檔案


  1. 範例程式碼
    1. glob 走訪特定副檔名的檔案
    2. os.walk 走訪資料夾
    3. os.scandir
  2. 小結
  3. 參考資料

最近一個工作需求是要爬近 TB 等級的資料,資料的儲存格式是散落在各資料夾中的 XML 檔。然而實際爬蟲發現 IO 的瓶頸反而不是處理 XML 檔及萃取資料並寫入資料庫中,瓶頸是出現在走訪資料夾所花費的時間。原本想改用 Multi Thread / Process 的方式處理,無奈自己也不太熟悉。最後則是改採 glob 模組,讓搜尋資料夾中 XML 檔的效率增加,整體的作業時間就有相當明顯的改善!

logo

glob 是 python Built-in battery 的模組,所以不需要另外 pip install

範例程式碼

glob 走訪特定副檔名的檔案

glob.glob(pathname, *, recursive=False)

import glob
glob.glob('**/*.jpg', recursive=True)
#return a list

os.walk 走訪資料夾

os.walk(top, topdown=True, onerror=None, followlinks=False)

import os
os.walk('')
#return a Generator
#element of generator : (path, listDir, listFile)

from os import walk
for pathTuple in walk(r'\\UNC'):
  for file in pathTuple[2]:
    print(file)

os.scandir

回傳 DirEntry Generator 的物件,相比 os.listdir 是回傳資料夾下的檔案或目錄名稱。
Dir Entry 多了 is_dir(), is_file(), name, path 等 API 更為方便。

os.scandir(path=None)

dirEntry = next(os.scandir())
# return a DirEntry Generator
dirEntry.name
dirEntry.path
dirEntry.is_dir()
dirEntry.is_file()

小結

最後這個任務的處理,採用的是先匯出 (dir /b /s) 所有 XML path 成一個檔案,讓 python 讀取該檔案後直接逐行存取 XML 檔案,讓每次測試都需要重新費時的走訪工作省略,同時也可以預先掌握到需要處理的檔案總數。只是會讓檔案的讀取變得不即時,解決方式是反覆再依據修正時間來重新匯出並加以更新。

參考資料