第四章 補充教材

1.Python來抓取政府公開資料(CSV):空氣品質



什麼是CSV?

CSV (Comma-Separated Values,逗號分隔值為常見的一種「純文字」資料儲存的檔案格式,將所有資料以半形的逗號隔開,一般的試算表軟體均能處理並儲存CSV格式。

例如環保署的「空氣品質指標(AQI)」開放資料格式就有提供CSV跟JSON格式(如下圖),點擊CSV右邊的「檢視資料」:

image-1639670126680.png

畫面上方會有一個「資料下載網址」,可以先複製起來(等一下寫程式會用到),下方也會有資料的預覽:

image-1639670247199.png

點一下「資料下載網址」就能下載該CSV檔,用LibreOffice Calc或Excel來開啟,開啟的畫面如下圖。

image.png

CSV檔可以用一般文字編輯軟體來開啟,例如用記事本開啟的畫面如下圖,無法像試算表軟體那樣對齊:

image-1639670672053.png


用Python處理線上的CSV資料


Python處理CSV檔的方式與JSON不同,可以先參考以下範例:

import  urllib.request,csv
url = 'CSV檔的網址'
webpage = urllib.request.urlopen(url)  #開啟網頁
data = csv.reader(webpage.read().decode('utf-8').splitlines()) #讀取資料到data陣列中
for i in data:
    print('測站->',i[0],'縣市=',i[1], 'AQI=',i[2])   

因為CSV的資料已經儲存到「data」這個二維陣列中了,所以用 for i in data: 之後,i就變成了一維陣列,索引值從0開始編號,所以i[0]就是「SiteName」、i[1]變成「County」、i[5]就是「SO2」……,依此類推。

image-1639670835362.png


上面的程式 執行後的結果如下:

image-1639671010933.png

(以下省略)


練習:修改以上程式碼,讓使用者可以輸入觀測站名稱(例如忠明)或縣市(如臺中市),列出符合該關鍵字的觀測站所量測到的AQI值及PM 2.5。





用Python來抓取政府公開資料(JSON)

 

 

尋找開放資料

1.使用瀏覽器打開「政府資料開放平台」:  https://data.gov.tw/ 

2.進入「求學及進修」,在上方搜尋輸入「高中」,可找到「高級中等學校科別資料

3.找到108學年度,點擊前面的「檢視資料」:

image-1620262809151.png

4. 先確定資料的編碼格式是否為「UTF-8」 (萬國碼之一),下方並提供「JSON下載」。

目前先以JSON格式進行練習,若資料不提供JSON格式暫勿使用。

5.將滑鼠游標移到「JSON下載」後面的網址上方,按下滑鼠右鍵並點選【複製連結網址】。例如:

https://quality.data.gov.tw/dq_download_json.php?nid=9617&md5_url=fc93547438b2106ccec5f9b6b112c0bd

6.進入Python開發環境IDLE,開啟新檔案,複製以下範例程式碼並進行修改:

import  json, ssl, urllib.request

url = 'JSON下載的網址'
context = ssl._create_unverified_context()

with urllib.request.urlopen(url, context=context) as jsondata:
    #將JSON進行UTF-8的BOM解碼,並把解碼後的資料載入JSON陣列中
     data = json.loads(jsondata.read().decode('utf-8-sig')) 

for i in data:
      print(i['學校名稱'],'\t',i['一年級男學生數'],'\t',i['一年級女學生數'])

上例中的「學校名稱」、「一年級男學生數」及「一年級女學生數」可依照「資料資源欄位」自行修改。

7.執行之後會出現以下畫面:

(以下略)

 

練習1:請顯示所有高中的一至三年級男女生學生數

 

 

資料的計算

 

如果要統計公開資料裡面的數字,我們可以將程式略做修改,例如我們想計算全台高一男女生的人數,我們可以將資料加總。

把原來的 for i in data 迴圈改寫成:

boy=0   #男生數 變數
girl=0  #女生數 變數

for i in data:
         boy += int(i['一年級男學生數'])
         girl += int(i['一年級女學生數'])


print("高一男生總數=", boy, '女生總數=', girl)
     

 

練習2:請加總所有高中的高一二三男女生之學生數

 

資料的搜尋

 

如果我們想讓使用者依照關鍵字列出資料,可以先用input取得關鍵字,然後使用if ,配合 find 函數:

字串變數.find(要搜尋的字串)

例如:

a="This is a book"
b="a"
print(a.find(b))

結果為8  

意思就是b字串出現在a字串的第幾個字(第一個字的位置是0),如果>=0 表示a字串中有b字串,否則傳回-1

 

因此我們可以將這個搜尋函數應用在資料的搜尋上,例如school字串變數是使用者要搜尋的學校名稱,只要在i的for迴圈中,加上 if i['學校名稱'].find(school) >= 0  就表示學校名稱中含有使用者要搜尋的文字:

執行結果為:

練習3:讓使用者輸入校名的關鍵字,計算顯示所有高中各科別的一至三年級班級數  (結果要截圖上傳)

 

其他開放資料的應用

 

練習4:請自行找一項政府開放資料,試著統計或列出裡面你感興趣的資料  (必須有搜尋功能,結果截圖上傳)

 

 

 

 

 

 如何安裝Python套件

 

  1. 進入命令列模式:開始→執行 (或按下Windows + R)→輸入 CMD )

  2. 升級pip(Python套件管理工具):輸入 python -m pip install --upgrade pip 
  3. 安裝套件: pip install requests

電腦教室已安裝,不用執行以上動作

 

用Python來抓取政府公開資料(JSON) (新!) :台中 YouBike 2.0

台中iBike公開資料

1.先到台中市政府資料開放平台(https://opendata.taichung.gov.tw


image.png

在搜尋欄位輸入【公共自行車】:

螢幕擷取畫面 2023-12-21 141123.jpg

目前iBike只提供JSON格式資料可下載:

image.png

下方提供資料的欄位說明:

image-1620792682503.png

點擊「JSON」下載後,在【下載】的上方按下滑鼠右鍵選擇【複製下載連結】,就會取得 JSON的下載網址:

image.png

2022/12更新﹔

推測可能是線上的JSON檢視器耗費太多伺服器的資源,因此已經被取消,建議使用另一個線上JSON檢視器:

https://jsoneditoronline.org/

image.png

按下【Copy】下方的【>】,就能在右側看到解析出來的資料了。

image.png


Python程式撰寫


因為台中市iBike的資料格式非標準格式,寫法會有所不同,程式需要略為修改。

import  json, ssl, urllib.request

url = 'JSON下載網址'
context = ssl._create_unverified_context()

with urllib.request.urlopen(url, context=context) as jsondata:
    #將JSON進行UTF-8的BOM解碼,並把解碼後的資料載入JSON陣列中
     data = json.loads(jsondata.read().decode('utf-8-sig')) 


for i in range(len(data["retVal"])) :
    sna = data["retVal"][i]["sna"]    #站名
    tot = data["retVal"][i]["tot"]    #總車位數
    sbi = data["retVal"][i]["sbi"]    #車輛數
    bemp = data["retVal"][i]["bemp"]    #空位數
    print(sna ,"車位數",tot, "車輛數=",sbi, " 空位數=",bemp)

執行結果:

image.png

練習:請問要加上站點的地址,要怎麼寫?


資料的搜尋


如果我們想讓使用者依照關鍵字列出資料,可以先用input取得關鍵字,然後使用if ,配合 find 函數:

字串變數.find(要搜尋的字串)

例如:

a="This is a book"
b="a"
print(a.find(b))

結果為8  

意思就是b字串出現在a字串的第幾個字(第一個字的位置是0),如果>=0 表示a字串中有b字串,否則傳回-1


因此我們可以將這個搜尋函數應用在資料的搜尋上,例如keyword字串變數是使用者要搜尋的站點名稱,只要在for迴圈中,加上 if sna.find(keyword) >= 0 就表示站名中含有使用者要搜尋的文字。

keyword = input("請輸入站名的關鍵字==>")

練習:只要列出符合關鍵字的站點,該怎麼改寫?

用Python來抓取政府公開資料(JSON):空氣品質

一、尋找開放資料

 

政府資料開放平台(https://data.gov.tw/

搜尋「空氣品質指標」,或直接打開網址:https://data.gov.tw/dataset/40448 

選擇「JSON」格式

image-1620793287044.png

 

資料欄位的說明及下載網址:

image-1620793319771.png

二、撰寫程式

程式碼範例如下,請自行修改要顯示的欄位名稱(以下以SiteName、AQI及Status為例):

import  json, ssl, urllib.request

url = 'JSON下載網址'
context = ssl._create_unverified_context()

with urllib.request.urlopen(url, context=context) as jsondata:
    #將JSON進行UTF-8的BOM解碼,並把解碼後的資料載入JSON陣列中
     data = json.loads(jsondata.read().decode('utf-8-sig')) 

for i in data['records']:
      print(i['SiteName'],' AQI=',i['AQI'], ' 狀態=', i['Status'])

 

執行結果:

image-1620793188522.png

 

三、改寫程式

請自行改寫程式,可提供以下功能:

 

 

陣列加上亂數的應用

 

抽籤(樂透抽號)程式

 

import random

lottery=[]  #存放彩球的陣列
total = 49  #彩球的數量
num = 6       #要抽的彩球數

for i in range(1, total+1):
       #將數字加入彩球陣列 (兩種寫法擇一)
        #lottery.append(i)
        lottery += [i]
             

for i in range(num):

    n = random.randint(0, total-1)  #隨機產生抽出彩球的位置
    print(lottery[n], end=" ")  # 印出抽到的牌
    del lottery[n]  #從彩球陣列刪掉抽到的球
    total -= 1   #將彩球數減一

 

撲克牌發牌程式

 

import random

card_color=['♠','♥','♦','♣']   #牌的花色陣列
card_number=['A','K','Q','J','10','9','8','7','6','5','4','3','2']  #牌的數字陣列
card=[]  #存放撲克牌的陣列

for i in card_color:
    for j in card_number:
        #加牌的花色及數字加到撲克牌的陣列(兩種寫法擇一)
        #card.append(i + j)
        card += [ i + j ]
             
total = 52  #總共要發幾張牌


for i in range(total):

    n = random.randint(0, total-1)  #隨機產生抽牌的位置
    print(card[n], end="  ")  # 印出抽到的牌
    del card[n]  #從card陣列刪掉抽到的牌
    total -= 1   #將牌的張數減一

    if (i+1) % 13 == 0:   #每發13張
         print()          #換行

 

 

課程學習成果參考範例

一、學習歷程檔案資料格式規定

 

 

二、資料製作方向

 

請先用文書軟體編排以下內容(非制式,僅供參考):

 

三、範例:僅供參考

 

 

 

 

 

 

[舊]用Python來抓取政府公開資料(CSV)

 

 

什麼是CSV?

CSV (Comma-Separated Values,逗號分隔值為常見的一種「純文字」資料儲存的檔案格式,將所有資料以半形的逗號隔開,一般的試算表軟體均能處理並儲存CSV格式。

例如健保署的「健保特約機構口罩剩餘數量明細清單」開放資料格式提供的就是CSV檔:

下載該CSV檔,用Excel開啟的畫面如下圖:

CSV檔可以用一般文字編輯軟體來開啟,例如用記事本開啟的畫面如下圖,無法像試算表軟體那樣對齊:

 

用Python處理線上的CSV資料

 

Python處理CSV檔的方式與JSON不同,可以先參考以下範例:

import  urllib.request,csv
url = 'CSV檔的網址'
webpage = urllib.request.urlopen(url)  #開啟網頁
data = csv.reader(webpage.read().decode('utf-8').splitlines()) #讀取資料到data陣列中
for i in data:
    print('名稱->',i[1],'成人口罩=',i[4], '兒童口罩=',i[5])   

因為CSV的資料已經儲存到「data」這個二維陣列中了,所以用 for i in data: 之後,i就變成了一維陣列,索引值從0開始編號,所以i[0]就是「醫事機構代碼」、i[1]變成機構名稱、i[4]就是成人口罩剩餘數……等。

 

上面的程式 執行後的結果如下:

(以下省略)

 

練習:修改以上程式碼,讓使用者可以輸入藥局的名稱(例如中市西屯區衛生所)或地址(如臺中市西屯區),列出符合該關鍵字的藥局所剩的成人及兒童口罩數量。

 

 

 

 

[舊]用Python來抓取政府公開資料(JSON) -3 :台中 iBike

台中iBike公開資料

1.先到台中市政府資料開放平台(https://opendata.taichung.gov.tw

image-1620792598996.png

捲到下方找到iBike的即時車位資料:

image-1620792591823.png

目前iBike只提供JSON格式資料可下載:

image-1620792658332.png

下方提供資料的欄位說明:

image-1620792682503.png

點擊右方的「探索」,在【下載】的上方按下滑鼠右鍵選擇【複製連結網址】,就會取得 JSON的下載網址:

image.png

2022/12更新﹔

推測可能是線上的JSON檢視器耗費太多伺服器的資源,因此已經被取消,建議使用另一個線上JSON檢視器:

https://jsoneditoronline.org/

image.png

按下【Copy】下方的【>】,就能在右側看到解析出來的資料了。

image.png


Python程式撰寫


因為台中市iBike的資料格式非標準格式,寫法會有所不同,程式需要略為修改。

import  json, ssl, urllib.request

url = 'JSON下載網址'
context = ssl._create_unverified_context()

with urllib.request.urlopen(url, context=context) as jsondata:
    #將JSON進行UTF-8的BOM解碼,並把解碼後的資料載入JSON陣列中
     data = json.loads(jsondata.read().decode('utf-8-sig')) 

for key,value in data["retVal"].items():
    sna = value["sna"]    #站名
    sbi = value["sbi"]    #車輛數
    bemp = value["bemp"]  #空位數
    print(sna , "車輛數=",sbi, " 空位數=",bemp)

執行結果:

image-1620792902751.png

練習:請問要加上站點的地址,要怎麼寫?


資料的搜尋


如果我們想讓使用者依照關鍵字列出資料,可以先用input取得關鍵字,然後使用if ,配合 find 函數:

字串變數.find(要搜尋的字串)

例如:

a="This is a book"
b="a"
print(a.find(b))

結果為8  

意思就是b字串出現在a字串的第幾個字(第一個字的位置是0),如果>=0 表示a字串中有b字串,否則傳回-1


因此我們可以將這個搜尋函數應用在資料的搜尋上,例如keyword字串變數是使用者要搜尋的站點名稱,只要在for迴圈中,加上 if sna.find(keyword) >= 0 就表示站名中含有使用者要搜尋的文字。

keyword = input("請輸入站名的關鍵字==>")

練習:只要列出符合關鍵字的站點,該怎麼改寫?

[舊]用Python來抓取政府公開資料(JSON) -2 :YouBike 2.0

一、台北市YouBike 2.0

(一) 尋找開放資料

1.使用瀏覽器打開「台北市資料大平臺」: https://data.taipei/

image-1620265870330.png

2.輸入「youbike」,即可找到YouBike2.0 即時資訊, 點擊後按下右邊的放大鏡來搜尋。

image-1620265899058.png

4. 可看到右上角有「下載」就是資訊介接的網址,下方有主要欄位說明。image-1620266012605.png

(二)程式撰寫

進入Python開發環境IDLE,開啟新檔案,複製以下範例程式碼並進行修改:

import  json, ssl, urllib.request

url = 'JSON下載的網址'
context = ssl._create_unverified_context()

with urllib.request.urlopen(url, context=context) as jsondata:
    #將JSON進行UTF-8的BOM解碼,並把解碼後的資料載入JSON陣列中
     data = json.loads(jsondata.read().decode('utf-8-sig')) 

for i in data:
      print(i['sna'],'\t',i['sbi'],'\t',i['bemp'])

上例中的「sna」、「sbi」及「bemp」可依照「資料資源欄位」自行修改。

執行之後會出現以下畫面:

image-1620266156529.png

(以下略)


練習1:請顯示所有YouBike站的可借數量及空位數量



(三)資料的計算


如果要統計公開資料裡面的數字,我們可以將程式略做修改,例如我們想計算全部YouBike站的車輛數及空位數,我們可以將資料加總。

把原來的 for i in data 迴圈改寫成:

bike=0   #場站目前車輛數量 變數
empty=0  #空位數量 變數

for i in data:
         bike += int(i['sbi'])
         empty += int(i['bemp'])

print("全部車輛數量=", bike, '全部空位數量=', empty)     


練習2:請加總所有YouBike站車輛及空位數量

(四)資料的搜尋


如果我們想讓使用者依照關鍵字列出資料,可以先用input取得關鍵字,然後使用if ,配合 find 函數:

字串變數.find(要搜尋的字串)

例如:

a="This is a book"
b="a"
print(a.find(b))

結果為8  

意思就是b字串出現在a字串的第幾個字(第一個字的位置是0),如果>=0 表示a字串中有b字串,否則傳回-1


因此我們可以將這個搜尋函數應用在資料的搜尋上,例如name字串變數是使用者要搜尋的站名,只要在i的for迴圈中,加上 if i['sna'].find(name) >= 0 就表示學校名稱中含有使用者要搜尋的文字:

image-1620266645513.png

執行結果為:

image-1620266615874.png五)ㄠ

練習3:讓使用者輸入站名或地址的關鍵字,列出空位有10個以上的站點之車輛及空位數量 (結果要截圖上傳)

(五)其他開放資料的應用


練習4:請自行找一項政府開放資料,試著統計或列出裡面你感興趣的資料  (必須有搜尋功能,結果截圖上傳)


(六)上面這隻程式可以用在哪種JSON資料?

只要JSON格式的最前面是 [ { 開頭,接下來就直接是資料的欄位名稱 這種JSON大部分可用以上程式。

例如:「臺中市路邊停車收費路段」

image-1639669538550.png

不過有些JSON格式使用了二維陣列(例如「臺中市停車場剩餘車位」),如下圖,陣列裡面還有陣列(就是中括號裡面還有中括號),上面的程式就無法正確執行了,必須加以改寫。

image-1639669763773.png