Python 爬蟲 – 連結追蹤與 Excel 讀取

前一篇文章 宅宅工程師的強迫症 – 有病要看,有bug就一定要解 裡提到,對政府的網站資料做爬蟲。裡面用到了一些新技巧,寫一篇文章把它紀錄分享下來。

這兩樣新技術(技巧)分別是:

  1. 連結追蹤:以往爬蟲都是指定好頁面去抓該頁的資料,此次則是要從指定頁面往下深入三四層連結才能抓到資料。有人會問怎麼不先自己進去兩三層抓到最後的網址就好了?這樣不能說錯,但這是業主指定的方式,也不好反駁,也許將來真的連結會改變。
  2. Excel檔案資料讀取:最後都會抓到 Excel 的檔案,要把裡面的內容讀出來。

這次的網頁沒有JavaScript而需要使用到 Selenium 的工具來處理,要是有的話真的蠻頭大的,Selenium 又慢又肥…

連結追蹤

連結追蹤就是一層層的,進入指定文字所連結到的網址。要找到正確的連結,關鍵還是在於該連結的文字是否夠獨特。若有很多結構相似的文字,這樣難度就會增加,需要做更多的判斷。這功能的程式碼說到底,就是有層次的找到指定的關鍵字,把最符合的取出來。

簡單版 – 指定的網頁就有 XLS 檔

比較簡單的,給定的URL該頁就有 XLS 檔案

 

主要有5個function

  1. get_page() : 取得網頁 HTML 原始碼
  2. save_file():將指定的網址存成檔案
  3. find_xls_link():找到指定 URL 裡含有 “.xls” 的行,並以【”】切割後返回,以做後續處理
  4. get_xls_link():將 find_xls_link() 返回的內容做判斷,將資訊組合成一個 dict 結構返回
  5. get_normal():將一個確定包含 .xls 檔案的 URL 傳入,並下載該檔。

針對簡單的網頁,就直接呼叫 get_normal() 來下載檔案。 get_normal() 會呼叫 get_xls_link() 取得真實的連結,然後再以 save_file() 來存檔。get_xls_link() 的過程中會使用到 find_xls_link() 與 get_page() 來 parse 網頁 HTML 的內容,以判斷要下載的網址在哪。

複雜版 – 追蹤數層後才得知下載頁面

簡單版和複雜版的差別,在於簡單版一開始就知道最終包含 .xls 檔的是哪個頁面,而複雜版需跟隨幾個頁面後才會知道。其實如果這些連結都不會變動,只要一開始手動去找出最終 .xls 的連結就可以了。不過我想業主是怕往後會有變動,順便學習一下如何爬蟲,才會有些需求。

 

除了簡單版的 function 外,另外有三個主要的 function

  1. get_text_hyperlink():在指定的 HTML 內容中,先找到第一個關鍵字所在的行,然後再找到第二個關鍵字所在的行。以雙引號做切割後,返回第一個。這個行為其實跟他的網頁內容、編排方式很有相關。只要其排版方式改變,程式碼就要修改。這也是為何爬蟲是客制化程度很高的程式。
  2. go_next_level_url():取得的下一層連結,並把網址做一些處理,主要是把相對路徑轉成絕對路徑。
  3. _get_4_1_13():為了取得 4.1.13 章結節檔案 (也就是複雜版的章節),所客制化的function。它的共通點是要往下追蹤四層連結,前面兩層是共通的,後面兩層則不同。

 

讀取 Excel XLS 檔案內容

前面一個部份是解說跟隨超連結網頁的程式,另一個重點部份則是讀取 Excel 檔案。讀取 Excel 檔案,有兩個比較通用的套件 xlrdopenpyxl。據不認真的查証, xlrd 處理 .xls 檔做的比較齊全,對 .xlsx 只有基本功能。而 openpyxl 只能讀 .xlsx,不支援 .xls,xlsx功能(應該)比較齊全。

這個案子的檔案則 .xls 與 .xlsx 檔都有,好在都只是基本的讀取。所以就一律用 xlrd 套件來處理。

直接以一個範例來說明如何使用這個套件。下面的例子會開啟一個名為 test.xls 的檔案,並把每一個sheet的名稱和 A1 欄位印出來。

上面的例子會印出下面的結果

 

程式碼

雖然案子沒接到,也沒用到業主任何的程式碼。但為免對其造成困擾,可能過三個月後把程式稍做精簡後在放上來。

 

Leave a Reply