所有入門單元免費開放 · 課程內容持續更新中

用 requests 串接網路 API

用 requests 向免費的天氣 API 要資料,看懂狀態碼,加上逾時與錯誤處理,寫出一支「今天要不要帶傘」的小程式。

第 2.4 堂約 15 分鐘

API 是什麼?

你在手機上查天氣時,App 並不是自己量溫度,而是去問氣象資料的伺服器:「台北現在幾度?」伺服器回傳一包資料,App 再把它畫成漂亮的畫面。

這個「讓程式去問另一個程式」的窗口,就叫 API。學會呼叫 API,你的 Python 程式就能取得天氣、匯率、公車到站時間這類即時資料。很多 AI 服務本身也是透過 API 使用的。

這堂課用 Open-Meteo,一個免費、不用註冊、不用金鑰的天氣 API。上一堂學的 JSON,馬上就派上用場。

請求與回應示意圖:你的 Python 程式送出包含網址和參數的請求給 Open-Meteo 伺服器,伺服器回傳狀態碼 200 和 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() 效果一樣。

網址結構示意圖:https://api.open-meteo.com 是伺服器位址,/v1/forecast 是路徑,問號後面是一組一組用「and 符號」連接的參數,例如 latitude=25.04

狀態碼:先看伺服器怎麼說

每次回應都會帶一個三位數的狀態碼,告訴你這次請求的結果:

狀態碼 意思 你該做什麼
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 是很好的翻譯和導遊。

可以這樣問 Claude

我想用 Python 的 requests 呼叫 Open-Meteo 的天氣預報 API,查高雄未來 3 天每天的最高溫和降雨機率。請告訴我要用哪些參數,並寫一段有 timeout 和錯誤處理的範例程式。另外,請附上 Open-Meteo 官方文件的網址,讓我可以自己核對參數名稱。

最後那句很重要:AI 偶爾會記錯參數名稱,或用到已經改版的寫法。以官方文件為準,執行一次、看狀態碼和回傳內容,才算數。

行動練習
  1. 安裝 requests,執行「第一次呼叫 API」的程式,印出台北現在的溫度。
  2. 把經緯度換成你住的地方(可以在地圖 App 長按地點取得),再查一次。
  3. 故意把參數名稱打錯,看看狀態碼和 reason 寫了什麼。
  4. 完成 get_today_weather 版本,讓它依照降雨機率提醒你要不要帶傘。

把這支程式留著,下一堂要讓它每天早上自己執行。

讀完了嗎?

標記完成後,單元與專案的進度會自動更新(只存在這台裝置的瀏覽器)。

卡住了?讓 AI 當你的家教複製這段提問範本,貼到 Claude 或其他 AI 工具,再補上你卡住的地方。

留言與討論

卡關了、有心得,或發現內容需要更新?都歡迎留言。留言使用 GitHub 帳號登入。

留言區即將開放。現在可以先到 GitHub 討論區 發問,或看看 交流頁 的其他管道。