用 requests 串接網路 API
用 requests 向免費的天氣 API 要資料,看懂狀態碼,加上逾時與錯誤處理,寫出一支「今天要不要帶傘」的小程式。
API 是什麼?
你在手機上查天氣時,App 並不是自己量溫度,而是去問氣象資料的伺服器:「台北現在幾度?」伺服器回傳一包資料,App 再把它畫成漂亮的畫面。
這個「讓程式去問另一個程式」的窗口,就叫 API。學會呼叫 API,你的 Python 程式就能取得天氣、匯率、公車到站時間這類即時資料。很多 AI 服務本身也是透過 API 使用的。
這堂課用 Open-Meteo,一個免費、不用註冊、不用金鑰的天氣 API。上一堂學的 JSON,馬上就派上用場。
送出請求,拿回回應。回應裡有狀態碼和資料。
安裝 requests
requests 是 Python 最常用的網路請求套件:
python -m pip install requests
第一次呼叫 API
import requests
URL = "https://api.open-meteo.com/v1/forecast"
params = {
"latitude": 25.04,
"longitude": 121.56,
"current": "temperature_2m",
"timezone": "Asia/Taipei",
}
resp = requests.get(URL, params=params, timeout=10)
print(resp.status_code)
data = resp.json()
print(data["current"]["temperature_2m"])
200
23.4
(溫度是即時資料,你看到的數字會不一樣。)
拆開來看:
latitude、longitude是緯度和經度,這裡是台北市中心附近。換成你家的座標,就能查你那裡的天氣。params是一個字典,requests會自動把它接在網址後面,變成?latitude=25.04&longitude=121.56...的樣子。timeout=10是「最多等 10 秒」。沒設定的話,遇到網路不穩,程式可能會一直卡在那裡。resp.json()把回傳的 JSON 文字轉成 Python 字典,跟上一堂的json.loads()效果一樣。
狀態碼:先看伺服器怎麼說
每次回應都會帶一個三位數的狀態碼,告訴你這次請求的結果:
| 狀態碼 | 意思 | 你該做什麼 |
|---|---|---|
| 200 | 成功 | 繼續處理資料 |
| 400 | 請求有誤,通常是參數寫錯 | 檢查參數名稱和格式 |
| 404 | 找不到這個網址 | 檢查網址有沒有打錯 |
| 429 | 請求太頻繁 | 等一下再試,不要用迴圈狂打 |
| 500、503 | 對方伺服器出問題 | 不是你的錯,晚點再試 |
試著把 "current" 的值改成一個不存在的名字,例如 "temp",你會拿到 400,而且回傳的 JSON 裡會有一段 reason 說明哪裡不對。讀錯誤說明,是串接 API 最重要的習慣。
加上錯誤處理
網路的世界什麼都可能發生:Wi-Fi 斷線、伺服器維修、回應太慢。我們用 try 和 except 把可能出錯的部分包起來:
import requests
URL = "https://api.open-meteo.com/v1/forecast"
def get_today_weather(lat, lon):
params = {
"latitude": lat,
"longitude": lon,
"daily": "temperature_2m_max,temperature_2m_min,precipitation_probability_max",
"timezone": "Asia/Taipei",
"forecast_days": 1,
}
try:
resp = requests.get(URL, params=params, timeout=10)
resp.raise_for_status()
except requests.exceptions.Timeout:
print("連線逾時,等一下再試試看")
return None
except requests.exceptions.RequestException as e:
print(f"取得天氣失敗:{e}")
return None
return resp.json()["daily"]
daily = get_today_weather(25.04, 121.56)
if daily:
high = daily["temperature_2m_max"][0]
low = daily["temperature_2m_min"][0]
rain = daily["precipitation_probability_max"][0]
print(f"今天 {low}~{high} 度,降雨機率 {rain}%")
if rain >= 50:
print("記得帶傘!")
今天 19.8~25.6 度,降雨機率 60%
記得帶傘!
try裡面放「可能會出錯」的程式。真的出錯時,Python 不會整個當掉,而是跳到對應的except。raise_for_status()會在狀態碼不是成功(例如 400、500)時,主動丟出錯誤,讓except接住。RequestException是requests所有網路錯誤的總稱,放在最後當作「其他狀況都在這裡處理」。- 函式出錯時回傳
None,所以外面用if daily:檢查有沒有拿到資料。
daily 裡的每個欄位都是串列,因為 API 可以一次給好幾天的預報。我們只要今天,所以取 [0]。
讓 AI 幫你讀 API 文件
每個 API 都有自己的說明文件,寫著有哪些網址、哪些參數。文件常常很長又是英文,這時 AI 是很好的翻譯和導遊。
我想用 Python 的 requests 呼叫 Open-Meteo 的天氣預報 API,查高雄未來 3 天每天的最高溫和降雨機率。請告訴我要用哪些參數,並寫一段有 timeout 和錯誤處理的範例程式。另外,請附上 Open-Meteo 官方文件的網址,讓我可以自己核對參數名稱。
最後那句很重要:AI 偶爾會記錯參數名稱,或用到已經改版的寫法。以官方文件為準,執行一次、看狀態碼和回傳內容,才算數。
- 安裝 requests,執行「第一次呼叫 API」的程式,印出台北現在的溫度。
- 把經緯度換成你住的地方(可以在地圖 App 長按地點取得),再查一次。
- 故意把參數名稱打錯,看看狀態碼和
reason寫了什麼。 - 完成
get_today_weather版本,讓它依照降雨機率提醒你要不要帶傘。
把這支程式留著,下一堂要讓它每天早上自己執行。
讀完了嗎?
標記完成後,單元與專案的進度會自動更新(只存在這台裝置的瀏覽器)。
留言與討論
卡關了、有心得,或發現內容需要更新?都歡迎留言。留言使用 GitHub 帳號登入。