【開放數據轉換PDF實戰】學Python程式做分析 逐步拆解年度計劃3

撰文:簡浩德
出版:更新:

《香港01》早前報道,政府以PDF格式公布政府83個部門的開放數據計劃,並就計劃內容進行分析。要分析這批資料,其中一個方法就是編寫程式以撮取資料,今次特別推出一系列文章,逐步講解如何利用程式,一次過將83個PDF轉為分析用數據,亦希望藉此讓讀者了解機讀格式檔如何有助分析。

【第4講】

TL;DR

1)下載 PDF 檔案
2)讀取 PDF 內容(使用 tabula 處理表格)
3)使用 Pandas 處理表格形式的資料

現時的問題(#7):有了 PDF 連結,下一步是?

進度表。

在取得了 PDF 檔案連結後,便可以使用「Requests」程式庫,把全部 PDF 檔案下載。所需加入程式碼如下(此處需要先新增資料夾,並命為「test_dl」):

請複製下列程式碼,並貼上到「純文字編輯程式」中(有顏色的程式碼為最新所加,需多加注意):

並且儲存成新一個 .py 檔案(詳情可參考這篇)。

有關執行上面的 Python 程式,則可參考這篇 。

經 Python 程式下載回來的「開放數據政策」年度計劃 PDF 檔案列表(只列出部分):

剛由 Python 程式下載回來的 PDF 檔案列表。

個別部門的 PDF 檔案容量相較其他略大,估計與 PDF 檔案內載有大量資訊所致。

以 PDF 的檔案大小由大至小排序顯示檔案列表。

接下來就是處理 PDF 檔案內容。亦即是處理數據中,佔時間最多,步驟最複雜䌓碎的資料清理(Data Cleansing)。

先前已經把多個 PDF 檔案下載到電腦中,只需從硬碟讀取便可,毋需每次都從政府部門網頁中下載。不過,如果政府網頁更新了其 PDF 檔案,就需要重新下載一遍,才能得到最新、最準確的資料。

在開始撰寫程式去讀取 PDF 檔案前,有幾項事情值得作思想準備。第一是,究竟寫程式會不會比人手重新用鍵盤輸入資料來得快速呢?第二是,需要檢視一下「開放數據政策」年度計劃的表格內容大致有哪些項目以及欄位。第三是,為何要合併多個部門的計劃文件去查看,不逐個檔案查閱呢?

第一,此處是示範使用程式進行半自動化處理資料,所以盡量不會考慮人手輸入。這次有 83 個 PDF 檔案,政府稱在 2019 年內會開放愈 650 個數據集。假設每一個數據集的紀錄,包括數據集名稱、目標發放日期、更新頻率連同備註的字數平均為 40 字。人手以每分鐘輸入 40 個䌓體中文字,所需時間為:650項 x 40字 / 40字每分鐘 = 約 650 分鐘,即近 11 小時。(按:實際統計每項目的平均字數約為 87 字,故以上述方法計算,輸入過程將需時愈 23 小時。)

第二,如果開發程式的時間比人手輸入來得少,就非常值得投入資源和時間開發程式去處理問題。假設政府的文件格式於下一個年度保持不變,程式便即可重用再重用,將節省更多人手輸入的時間,可以騰空資源做其他有趣有意義的事情。不過,事情總不如人願, 83 個政府部門有 83 個 PDF 檔案,很可能是由 83 個不同的政府人員負責編製,因此有 83 款的格式。

第三,製作一個全局省覽的方案是有必要。例如,可以知道相互比較哪個部門的數據集會比較多,也可以通過對全部項目分析後,譬如可得知在 1 月份完結之時,有甚麼數據集可以值得留意並已經發放等。

現時的問題(#8):打開手上的 PDF 檔案,怎樣整理不同部門的項目?

打開看每個 PDF 檔案先作檢視是需要的,否則不知道需要抽取哪些部分的資料出來。就 PDF 檔案表格內的欄目而言,有些 PDF 檔案的表格內會有數字編號欄目,欄目總數為 5 個。

行政長官辦公室「開放數據」年度計劃文件截圖。

有些 PDF 檔案則沒有編號的欄目,欄目總數僅為 4 個,不能與 5 個欄目的表格簡單地合併。更新頻率欄目名稱卻有「(例如:實時、每天、每星期、每月等)」字眼,嚴重障礙機讀程式把資料歸類。

懲教署「開放數據」年度計劃文件截圖。

而創新科技署的計劃文件,則插入惡名昭彰的「合併儲存格」(即該表格中灰色的部分),是令機讀程式不能正確處理的元兇。

創新科技署「開放數據」年度計劃文件截圖。

在計劃文件中,政府誓言旦旦會把越來越多的資料,以方便機讀格式發放,計劃文件本身卻仍舊沿用僅供人讀的格式去設計 PDF 檔案。

而知識產權署的年度計劃區區 11 頁,其 PDF 檔案竟達 5 MB,原來裡面放著圖片,而非文字形式作儲存,估計是非常擔心知識產權問題。(詳見「開放數據】政府計劃文件竟是83份PDF 要人手逐份下載逐份睇」

而政府統計處則是處理得宜的一個部門。它的表格是有 5 個欄目,比其他部門多一個「數據資源名稱」的欄目,與「資料一線通」網站架構相配對。

政府統計處之開放數據年度計劃截圖。

在「資料一線通」網站,其網頁架構正是由數據提供部門、數據集、數據資源這三個層級組成。政府統計處的數據集及數據資源眾多,所以在表格中一併展示將有助讀者快速對應「資料一線通」網站,檢索感興趣的開放數據。

現時的問題(#9):可以開始撰寫程式了嗎?

進度表。

還未可。

剛才的步驟,是資料清理(Data Cleansing)的前奏,就是資料探索(Data Exploration)。對資料先有一個大約概念,才能訂製資料結構的安排。 

在撰寫另一枝 Python 程式去讀取 PDF 檔案前,有一個程式庫需要安裝: tabula。一個可以讀取載有文字表格的 PDF 檔案,並輸出成 Pandas 資料方框(Data Frame)的程式庫。

安裝 tabula 這個程式庫。 在「命令列」(可參考這篇)中輸入「pip install tabula-py」,要注意必須是連帶-py 的「tabula-py」。

現在請複製下列程式碼,並貼上到「純文字編輯程式」中 (可參考這篇),並儲存成名稱為「read_pdf.py」(詳情可參考這篇)。

(注意,之前經 Python 程式下載回來的 PDF 檔案,是放置於「test_dl」的子資料夾中,以免 Python 不能找到相關的 PDF 檔案。)

運行結果如下:

使用 tabula 讀取一個 PDF 檔案的內容運行結果。

此處示範小試牛刀:讀取「漁農自然護理署」的計劃文件的第一頁。眼利的讀者會看到「數據種類/數據集名稱 」、「 Unnamed: 1」、「目標發放日期\r(月/年)」、「更新頻率\r(例如:實時、每天、每星期、每月等)」以及「備註」,共 5 個欄目,比從 PDF 瀏覽器中多了一個欄目。原因是程式把所有表格都放到同一個數據框,當中稍有不同,tabula 程式庫便會開設新欄目。但只要調校程式庫的參數,便可以將其分拆成多個表格,得出的結果欄目數量將會變一致。

修改如下,現在請複製下列程式碼,並貼上到「純文字編輯程式」中 (可參考這篇),儲存並且執行:

由於每個 PDF 檔的表格格式不一致,需要額外處理。當中更發現一些 PDF 檔案,程式讀取出來的文字是重複的,更有一些是表格內包含另一個表格,需要分開作特殊處理。

下列部門的計劃文件需要額外處理

編號

政府部門

所需額外處理

15

商務及經濟發展局

需把 PDF 轉存

18

香港懲教署

需把 PDF 轉存

20

衞生署

需把 PDF 轉存

24

教育局

需把 PDF 轉存

32

食物及衞生局

需把 PDF 轉存

34

政府飛行服務隊

需把 PDF 轉存

35

政府化驗所

需把 PDF 轉存

38

路政署

需把 PDF 轉存

46

入境事務處

需把 PDF 轉存

48

政府新聞處

需把 PDF 轉存

51

效率促進辦公室

需把 PDF 轉存

81

水務署

需把 PDF 轉存

82

學生資助處

需把 PDF 轉存

54

知識產權署

需要人手輸入

把 PDF 轉存的方法是利用 smallpdf.com 等線上服務轉換成 Microsoft Word 格式,然後再儲存回成 PDF 檔案。所得到的 PDF 檔案覆蓋本來由政府網頁下載回來的 PDF 檔案。

經過一番的嘗試,需將整份程式碼修改成如下,現在請複製下列程式碼,並貼上到「純文字編輯程式」中 (可參考這篇),儲存並且執行:

運行過程中的畫面截圖:

一併讀取83個 PDF 文件。

運行完畢後,將得到一個名為「opendata_policy2018_problems.csv」的 CSV 檔案。內裡是由 83 個政府部門的「開放數據政策」年度計劃 PDF 檔案轉換而來的純文字資料。

內容如下:

CSV 可用 Excel、Calc、Numbers、Spreadsheets 等試算表軟件或純文字編輯器開啟。

比較有用的欄目主要為「dept」、「備註」、「數據集名稱」、「更新頻率」、「發放日期」。當中「01_「資料一線通」內的數據資源名稱」本來同樣值得關注的欄目,可惜翻閱整份 CSV 檔案,原來只有政府統計處的計劃文件才有此項欄目,故放棄之。

小結:
行文至此讀者應該體會到整理雜亂不整齊格式數據的複雜程度。總的來說尚算有些許成果:把政府開放的 PDF 檔案,轉換成單一個機器可讀的 CSV 檔案。接下來就是要覆檢這個 CSV 檔案究竟與本身 PDF 檔案所載的內容是否一致。

下周再續...

注意事項:
此系列以 Windows 7 中文版 及 Python 3.7.2 於 2019年1月28日至31日期間測試,並力求有關資料於上述期間內準確,惟市面上不同電腦作業系統或會有不相同的執行結果,希望讀者理解。如有任何使用上的困難,請詳細參閱互聯網上其他相關資源,或向其他擁有此項相關專門知識的人士或機構進一步查詢。一切資料均以政府網頁公布為準,《香港01》將不為有關資料引起之任何損失或誤會負責。