《讓繁瑣工作自動化》十四、處理 CSV 文件和JSON 數據

《讓繁瑣工作自動化》十四、處理 CSV 文件和JSON 數據

來自專欄 Antenna的python學習筆記

1. 基礎語法

1.1 CSV模塊

(1)讀取CSV文件

csvobj = open(csvfile) #打開CSV文件readerpbj = csv.reader(csvobj) #將其轉換為reader對象

(2)寫入數據

output = open(csvfile, w, newline=) # 創建要寫入的CSV文件csvwriter = csv.writer(output) # 將其轉換為writer對象csvwriter.writerow(row) # 用writerow函數寫入數據

(3)關鍵字參數

csvwriter = csv.writer(csvfiel , delimiter = , lineterminator = nn) # delimiter參數為分隔符 lineterminator參數為間距

(4)實例應用

刪除許多CSV文件的第一行,重新寫入一個_removed文件

import csv,os#找尋當前路徑下所有CSVfor csvfile in os.listdir(.): if not csvfile.endswith(.csv): continue print(Remove header from +csvfile + ...) #將除第一行之外的所有行添加到列表中 csvrow = [] csvobj = open(csvfile) readerpbj = csv.reader(csvobj) for row in readerpbj: if readerpbj.line_num ==1: continue csvrow.append(row) csvobj.close() #寫入新CSV文件 output = open(Removed+csvfile,w) # output = open(os.path.join(RemovedHeader,csvfile),w,newline=) csvwriter = csv.writer(output) for row in csvrow: csvwriter.writerow(row) output.close()

1.2 JSON模塊

(1)json.loads()

將包含JSON數據的字元串轉換為Python的值

weatherData = json.loads(response.text)

(2)json.dumps()

講一個Python值轉換為JSON格式的字元串

value = {isCat:Truename:Zophie}Jsondata = json.dumps(value)

2.項目:從 CSV 文件中刪除表頭

假設你有一個枯燥的任務,要刪除幾百 CSV 文件的第一行。也許你會將它們送入一個自動化的過程,只需要數據,不需要每列頂部的表頭。可以在 Excel 中打開每個文件,刪除第一行,並重新保存該文件,但這需要幾個小時。讓我們寫一個程序來做這件事。

該程序需要打開當前工作目錄中所有擴展名為.csv 的文件,讀取 CSV 文件的內容,併除掉第一行的內容重新寫入同名的文件。這將用新的、無表頭的內容替換CSV 文件的舊內容。

與往常一樣,當你寫程序修改文件時,一定要先備份這些文件,以防萬一你的程序沒有按期望的方式工作。你不希望意外地刪除原始文件。

總的來說,該程序必須做到以下幾點:

? 找出當前工作目錄中的所有 CSV 文件。

? 讀取每個文件的全部內容。

? 跳過第一行,將內容寫入一個新的 CSV 文件。

在代碼層面上,這意味著該程序需要做到以下幾點:

? 循環遍歷從 os.listdir()得到的文件列表,跳過非 CSV 文件。

? 創建一個 CSV Reader 對象,讀取該文件的內容,利用 line_num 屬性確定要跳過哪一行。

? 創建一個 CSV Writer 對象,將讀入的數據寫入新文件。

針對這個項目,打開一個新的文件編輯器窗口,並保存為 removeCsvHeader.py。

第 1 步:循環遍歷每個 CSV 文件

#! python3# removeCsvHeader.py - Removes the header from all CSV files in the current# working directory.import csv, osos.makedirs(headerRemoved, exist_ok=True)# Loop through every file in the current working directory.for csvFilename in os.listdir(.): if not csvFilename.endswith(.csv): continue # skip non-csv files print(Removing header from + csvFilename + ...) # TODO: Read the CSV file in (skipping first row). # TODO: Write out the CSV file.

第 2 步:讀入 CSV 文件

#! python3# removeCsvHeader.py - Removes the header from all CSV files in the current# working directory.--snip--# Read the CSV file in (skipping first row).csvRows = []csvFileObj = open(csvFilename)readerObj = csv.reader(csvFileObj)for row in readerObj: if readerObj.line_num == 1: continue # skip first row csvRows.append(row)csvFileObj.close()# TODO: Write out the CSV file.

第 3 步:寫入 CSV 文件,沒有第一行

#! python3# removeCsvHeader.py - Removes the header from all CSV files in the current# working directory.--snip--# Loop through every file in the current working directory.for csvFilename in os.listdir(.): if not csvFilename.endswith(.csv): continue # skip non-CSV files --snip-- # Write out the CSV file. csvFileObj = open(os.path.join(headerRemoved, csvFilename), w, newline=) csvWriter = csv.writer(csvFileObj) for row in csvRows: csvWriter.writerow(row) csvFileObj.close()

第 4 步:類似程序的想法

針對 CSV 文件寫的程序類似於針對 Excel 文件寫的程序,因為它們都是電子表格文件。你可以編程完成以下任務:

? 在一個 CSV 文件的不同行,或多個 CSV 文件之間比較數據。

? 從 CSV 文件拷貝特定的數據到 Excel 文件,或反過來。

? 檢查 CSV 文件中無效的數據或格式錯誤,並向用戶提醒這些錯誤。

? 從 CSV 文件讀取數據,作為 Python 程序的輸入。

項目:取得當前的天氣數據

檢查天氣似乎相當簡單:打開 Web 瀏覽器,點擊地址欄,輸入天氣網站的 URL(或搜索一個,然後點擊鏈接),等待頁面載入,跳過所有的廣告等。

其實, 如果有一個程序,下載今後幾天的天氣預報,並以純文本列印出來,就可以跳過很多無聊的步驟。該程序利用第 11 章介紹的 requests 模塊,從網站下載數據。

總的來說,該程序將執行以下操作:

? 從命令行讀取請求的位置。

? 從 OpenWeatherMap.org 下載 JSON 天氣數據。

? 將 JSON 數據字元串轉換成 Python 的數據結構。

? 列印今天和未來兩天的天氣。

因此,代碼需要完成以下任務:

? 連接 sys.argv 中的字元串,得到位置。

? 調用 requests.get(),下載天氣數據。

? 調用 json.loads(),將 JSON 數據轉換為 Python 數據結構。

? 列印天氣預報。

針對這個項目,打開一個新的文件編輯器窗口,並保存為 quickWeather.py。

第 1 步:從命令行參數獲取位置

#! python3# quickWeather.py - Prints the weather for a location from the command line.import json, requests, sys# Compute location from command line arguments.if len(sys.argv) < 2: print(Usage: quickWeather.py location) sys.exit()location = .join(sys.argv[1:])# TODO: Download the JSON data from OpenWeatherMap.orgs API.# TODO: Load JSON data into a Python variable.

第 2 步:下載 JSON 數據

#! python3# quickWeather.py - Prints the weather for a location from the command line.--snip--# Download the JSON data from OpenWeatherMap.orgs API.url =http://api.openweathermap.org/data/2.5/forecast/daily?q=%s&cnt=3 % (location)response = requests.get(url)response.raise_for_status()# TODO: Load JSON data into a Python variable.

第 3 步:載入 JSON 數據並列印天氣

{city: {coord: {lat: 37.7771, lon: -122.42}, country: United States of America, id: 5391959, name: San Francisco, population: 0}, cnt: 3, cod: 200, list: [{clouds: 0, deg: 233, dt: 1402344000, humidity: 58, pressure: 1012.23, speed: 1.96, temp: {day: 302.29, eve: 296.46, max: 302.29, min: 289.77, morn: 294.59, night: 289.77}, weather: [{description: sky is clear, icon: 01d,--snip--

可以將 weatherData 傳入 pprint.pprint,查看這個數據。你可能要查找 openweathermap.org/,找到關於這些欄位含義的文檔。例如,在線文檔會告訴你, day後面的 302.29 是白天的開爾文溫度,而不是攝氏或華氏溫度。

你想要的天氣描述在main和 description之後。為了整齊地列印出來,在quickWeather.py 中添加以下代碼。

#! python3# quickWeather.py - Prints the weather for a location from the command line.--snip--# Load JSON data into a Python variable.weatherData = json.loads(response.text)# Print weather descriptions.w = weatherData[list]print(Current weather in %s: % (location))print(w[0][weather][0][main], -, w[0][weather][0][description])print()print(Tomorrow:)print(w[1][weather][0][main], -, w[1][weather][0][description])print()print(Day after tomorrow:)print(w[2][weather][0][main], -, w[2][weather][0][description])

如果用命令行參數 quickWeather.py San Francisco, CA 運行這個程序,輸出看起來是這樣的:

Current weather in San Francisco, CA:Clear - sky is clearTomorrow:Clouds - few cloudsDay after tomorrow:Clear - sky is clear

第 4 步:類似程序的想法

訪問氣象數據可以成為多種類型程序的基礎。你可以創建類似程序,完成以下任務:

? 收集幾個露營地點或遠足路線的天氣預報,看看哪一個天氣最好。

? 如果需要將植物移到室內,安排一個程序定期檢查天氣並發送霜凍警報(第15 章介紹了定時調度,第 16 章介紹了如何發送電子郵件)。

? 從多個站點獲得氣象數據,同時顯示,或計算並顯示多個天氣預報的平均值。

該項目因為openweathermap.org/網站自2015年以後需要註冊並申請認證key,相關代碼不能正常運行,會報:requestsHTTPError: 401 Client Error: Unauthorized for url

我在國內找到了一個可以使用的網站,並將代碼做了一點修改:

#! python3# quickWeather.py - Prints the current weather for a location from the command line.import json, requests, sys# Compute location from command line arguments.if len(sys.argv) < 2: print(Usage: quickWeather.py location) sys.exit()location = .join(sys.argv[1:])# Download the JSON data from OpenWeatherMap.orgs APIweatherJsonUrl = http://wthrcdn.etouch.cn/weather_mini?city= + location # 將鏈接定義為一個字元串response = requests.get(weatherJsonUrl) # 獲取並下載頁面,其內容會保存在respons.text成員變數裡面response.raise_for_status() # 這句代碼的意思如果請求失敗的話就會拋出異常,請求正常就什麼也不會做# Load JSON data into a Python variable.weatherData = json.loads(response.text)# Print weather descriptions.import pprint #導入pprint模塊pprint.pprint(weatherData) #漂亮列印出天氣字典w = weatherData[data][forecast]print(Current weather in %s: % (location))print(w[0][high], ,,w[0][low],-, w[0][type])print()print(Tomorrow:)print(w[1][high], ,,w[1][low],-, w[1][type])print()print(Day after tomorrow:)print(w[2][high], ,,w[2][low],-, w[2][type])

運行結果:

D:UsersAdministratorDesktopAutomate the Boring Stuff with Pythonautomate_online-materials>py quickWeather.py 懷柔{data: {city: 懷柔, forecast: [{date: 10日星期一, fengli: <![CDATA[<3級]]>, fengxiang: 南風, high: 高溫 26℃, low: 低溫 17℃, type: 多雲}, {date: 11日星期二, fengli: <![CDATA[<3級]]>, fengxiang: 南風, high: 高溫 24℃, low: 低溫 16℃, type: 多雲}, {date: 12日星期三, fengli: <![CDATA[<3級]]>, fengxiang: 南風, high: 高溫 27℃, low: 低溫 16℃, type: 多雲}, {date: 13日星期四, fengli: <![CDATA[<3級]]>, fengxiang: 東南風, high: 高溫 28℃, low: 低溫 19℃, type: 多雲}, {date: 14日星期五, fengli: <![CDATA[<3級]]>, fengxiang: 西風, high: 高溫 27℃, low: 低溫 18℃, type: }], ganmao: 各項氣象條件適宜,無明顯降溫過程,發生感冒機率較低。, wendu: 23, yesterday: {date: 9日星期日, fl: <![CDATA[<3級]]>, fx: 南風, high: 高溫 27℃, low: 低溫 14℃, type: }}, desc: OK, status: 1000}Current weather in 懷柔:高溫 26 , 低溫 17 - 多雲Tomorrow:高溫 24 , 低溫 16 - 多雲Day after tomorrow:高溫 27 , 低溫 16 - 多雲

這也是我喜歡待在懷柔的原因:)

3.小結

CSV 和 JSON 是常見的純文本格式,用於保存數據。它們很容易被程序解析,同時仍然讓人可讀,所以它們經常被用作簡單的電子表格或網路應用程序的數據。csv 和 json 模塊大大簡化了讀取和寫入 CSV 和 JSON 文件的過程。

前面幾章教你如何利用 Python 從各種各樣的文件格式的解析信息。一個常見的任務是接受多種格式的數據,解析它,並獲得需要的特定信息。這些任務往往非常特別,商業軟體並不是最有幫助的。通過編寫自己的腳本,可以讓計算機處理大量以這些格式呈現的數據。

在第 15 章,你將從數據格式中掙脫,學習如何讓程序與你通信,發送電子郵件和文本消息。

4.習題

1.哪些功能是 Excel 電子表格有,而 CSV 電子表格沒有?

Excel 電子表格的值可以是字元串以外的數據類型單元格可以有不同的字體大小或顔色設置單元格可以有不同的寬度和高度相鄰的單元格可以合併可以嵌入圖像和圖表

2.向 csv.reader()和 csv.writer()傳入什麼,來創建 Reader 和 Writer 對象?

傳入一個 File 對象,通過調用 open() 獲得。

3.對於 Reader 和 Writer 對象,File 對象需要以什麼模式打開?

對於 Reader 對象,File 對象需要以讀二進位模式(rb)打開,對於 Writer對象,需要以寫二進位模式(wb)打開。

4.什麼方法接受一個列表參數,並將其寫入 CSV 文件?

writerow() 方法。

5.delimiter 和 lineterminator 關鍵字參數有什麼用?

delimiter 參數改變了分隔一行中單元格所用的字元串。lineterminator 參數改變了分隔行的字元串。

6.什麼函數接受一個 JSON 數據的字元串,並返回一個 Python 數據結構?

json.loads()

7.什麼函數接受一個 Python 數據結構,並返回一個 JSON 數據的字元串?

json.dumps()

5 實踐項目

5.1 EXCEL到CSV的轉換程序

將當前路徑下的CSV文件全部輸出為CSV文件,一個Excel文件中可能包含多個工作表,必須為每個表創建一個CSV文件,重命名格式為 文件名_表標題.csv

# 2018/9/10 11:18import csv, openpyxl, osfor file in os.listdir(.): # Skip non-xlsx files, load the workbook object. if not file.endswith(.xlsx): # 不是xlsx文件就接著往下找 continue wb = openpyxl.load_workbook(file) sheets = wb.sheetnames # 找到當前文件中所有sheet for i in range(len(sheets)): # Loop through every sheet in the workbook. sheet = wb.get_sheet_by_name(sheets[i]) # 在sheets列表中依次循環找 # Create the CSV filename from the Excel filename and sheet title. print(正在寫入 + sheet.title + 文件) csvfilename = open(file.split(.)[0] + sheet.title + .csv, w) # Create the csv.writer object for this CSV file. csvwriter = csv.writer(csvfilename) # Loop through each cell in the row. for rownum in range(1, sheet.max_row + 1): # 循環每一個cell的值,將每一行寫入rowdata中 rowdata = [] # append each cell to this list # Loop through every row in the sheet. for colnum in range(1, sheet.max_column + 1): # Append each cells data to rowData. rowdata.append(sheet.cell(row=rownum, column=colnum).value) # Write the rowData list to the CSV file. csvwriter.writerow(rowdata) # 將每一行的值寫入csv文件中 csvfilename.close()

推薦閱讀:

如何實現PDF文檔自動朗讀?
pdf轉dwg格式轉換器怎麼用?
PDF文件怎麼進行拆分
牆內開花牆外香,也許是最優秀的全能型 PDF 應用

TAG:PDF | 文檔 | MicrosoftWord |