延續上一篇的內容,這篇就不贅述,以中央氣象局CODiS平台實際操作網路爬取氣候資料。
操作步驟:
1.了解HTML網頁語法基本編寫概念
在網頁上按F12可以瀏覽網頁原始碼,html架構由以下的基本元素組成。
² 網頁的所有內容會包含在< html> 和< /html> 標籤之間
² 網頁中重要元素或定義會放在< head>和< /head> 標簽之間,例如: 放置網頁標題的< title>標籤,就會放置在head裡面。
² 網頁中所呈現的內容(可視化的部份),會放於< body> 和< /body> 標籤之間。其中標示文章標題的標籤< h1>以及標示文章內文的標籤< p>都會放置於body標籤下。
2.查看頁面,確認可行的爬蟲方式
以中央氣象局CODiS平台為例,可能可行的方式有2種,(1)透過圖1”CSV下載”的方式直接下載CSV檔案 (2)爬取該網頁報表上的數值,再由程式轉換成檔案。
方式1:
從html原始碼中找到對應”CSV下載”標示的編碼(如下圖1、2)。這邊的編碼還另外包含了CSS的編碼,CSS為在html主架構下細部內容之編寫。在< a id=”downloadCSV” herf=”#”>這段內容中,herf後面接超聯結的路徑,但是這個網頁編碼後面接的是#而不是個路徑,這個#代表為前面的id,而id的屬性則在html中另外編輯屬性套用。所以看要再回去查看# downloadCSV那部份的程式編寫。不過查看後發現如果要透過路徑連結批量下載CSV檔的途徑似乎不可行,這部份讀者也可以自己再去確認看看。
圖1
圖2
網站管理員為了避免資料這麼容易被取得,所以將程式撰寫較為複雜,增加取得難度的情況相當常見,所以大家在爬蟲的時候不要一些挫折就氣餒。
方式2:
方式1的方法既然不可行,那就採用方式2,爬取整個頁面的表格數據,再整理CSV成檔案。這邊會用到3個套件,開始執行前,尚未安裝requests、BeautifulSoup及csv者需要先安裝,在Window環境下,開起命令提示字元,輸入pip install requests、 pip install bs4以及pip install csv,安裝完成後,後續以方式2的方式進行說明。
方式1的方法既然不可行,那就採用方式2,爬取整個頁面的表格數據,再整理CSV成檔案。這邊會用到3個套件,開始執行前,尚未安裝requests、BeautifulSoup及csv者需要先安裝,在Window環境下,開起命令提示字元,輸入pip install requests、 pip install bs4以及pip install csv,安裝完成後,後續以方式2的方式進行說明。
3.採用方法2,嘗試取得html解碼後標簽字串的回應內容
- import requests
- r=requests.get("http://e-service.cwb.gov.tw/HistoryDataQuery/MonthDataController.do?command=viewMain&station=466910&stname=%25E9%259E%258D%25E9%2583%25A8&datepicker=2019-08")
- print(r.text)

圖3
執行結果(圖3)大家可以看到,requests的請求取得整個網頁的資訊,大家可以在往下看到編寫網頁表格的部份,裡面有當月每日的氣候資料,截取部份資料如圖4,只是這樣的形式,我們無法直接利用,必須再處理成表格的樣式。
圖4
4.取出網站表格資料,寫入CSV檔案
- import requests
- from bs4 import BeautifulSoup
- import csv
- url="http://e-service.cwb.gov.tw/HistoryDataQuery/MonthDataController.do?command=viewMain&station=466910&stname=%25E9%259E%258D%25E9%2583%25A8&datepicker=2019-08" #網址
- csvfile="test.csv" #開個csv檔案準備寫入
- r=requests.get(url)
- r.encoding="utf-8"
- soup=BeautifulSoup(r.text,"lxml")
- tag_table=soup.find(id="MyTable") #用BeautifulSoup找到table位置
- rows=tag_table.findAll("tr") #找到每個
- with open(csvfile,"w+",newline="",encoding="utf-8") as fp:
- writer=csv.writer(fp)
- for row in rows:
- rowList=[]
- for cell in row.findAll(["td","th"]):
- rowList.append(cell.get_text().replace("\n","").replace("\r",""))
- writer.writerow(rowList)
利用BeautifulSoup套件中的find()函數找到最一開始
的標籤(圖5),再用findAll找出表格中每列
的標籤。再開啟csv檔,用迴圈的方式搭配findAll,讀取每一列有和細格的標籤,再用get_text()函數從cell取得數值,再利用append()函數將數值合併上去。最後再將每一列的數值寫到rowList中最後存到一開始創建的csv檔案中(test.csv)。
圖5
5.批次讀取
剛剛的執行只是完成一個頁面的爬蟲,再上一篇文章中,我們已經粗略估算過需要下載6萬個檔案。所以到這邊,不知道大家是否有注意到,網站上的網址有個規律性,不管換什麼樣的時間、什麼測站,網址會變動的只有標住顏色的部份。所以利用這個特性,寫迴圈置換會變動的部份,然後重覆執行剛剛那段程式,不管是要下載特定測站的資料或是限定特定期間的資料,透過網路爬蟲,都可以輕鬆取得。
剛剛的執行只是完成一個頁面的爬蟲,再上一篇文章中,我們已經粗略估算過需要下載6萬個檔案。所以到這邊,不知道大家是否有注意到,網站上的網址有個規律性,不管換什麼樣的時間、什麼測站,網址會變動的只有標住顏色的部份。所以利用這個特性,寫迴圈置換會變動的部份,然後重覆執行剛剛那段程式,不管是要下載特定測站的資料或是限定特定期間的資料,透過網路爬蟲,都可以輕鬆取得。
http://e-service.cwb.gov.tw/HistoryDataQuery/MonthDataController.do?command=viewMain&station=466910&stname=%25E9%259E%258D%25E9%2583%25A8&datepicker=2019-08
您好可以向您繼續請教後續回圈的寫法嗎?
回覆刪除