在這段時間的練習中,我學會了如何使用 API 取得資料、清理和分析這些資料。但在實際應用時,我們不會每天親自執行程式抓資料。
因此今天我要挑戰自動化,讓程式能夠在每天固定的時間自動執行,自己去抓取新資料並更新記錄。
這個讓程式自動定時跑的過程叫做排程(Scheduling)。
自動化省時間:
每天手動開啟程式拿資料非常麻煩,而排程能讓電腦自動在指定時間執行程式,完全不用人為操作。
定期更新資料:
像是天氣、匯率等資料會每天變動,使用排程可以每天自動抓最新資料並把結果更新到 CSV 檔或報表中。
符合真實應用場景:
很多實際服務像是 LINE 機器人、氣象系統、健康管理平台,都會利用排程功能達成資料每天自動同步和更新。
我今天的目標是讓程式能自動抓取天氣資料。我希望每天不用自己打開 Python,也不用手動執行程式,只要預先設定好排程,程式就會在指定時間自動去取得最新的天氣資訊,並且把結果存成 CSV 檔案。這樣我每天就能在固定的時間,拿到更新的天氣資料,像是建立一個會自動更新的氣象紀錄小系統。這次練習主要是讓我體驗「自動化」的概念,讓程式能更聰明、更省力地幫我完成工作。
步驟 0:準備環境
建立專案資料夾 day25
建立 .env
檔案,放 API 金鑰
OWM_API_KEY=我的OpenWeatherMap金鑰
CITY=Taipei
安裝必要套件:
pip install requests python-dotenv schedule
步驟 1:單次抓資料腳本
建立 day25_fetch_weather.py
這支程式會向 OpenWeatherMap 要資料,然後把結果寫進 output/weather_log.csv
。
import os, csv, sys
from datetime import datetime
from pathlib import Path
import requests
from dotenv import load_dotenv
API = "https://api.openweathermap.org/data/2.5/weather"
ROOT = Path(__file__).resolve().parent
OUT_DIR = ROOT / "output"
LOG_DIR = ROOT / "logs"
CSV_PATH = OUT_DIR / "weather_log.csv"
LOG_PATH = LOG_DIR / "day25.log"
def log(msg: str):
LOG_DIR.mkdir(parents=True, exist_ok=True)
ts = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
with open(LOG_PATH, "a", encoding="utf-8") as f:
f.write(f"[{ts}] {msg}\n")
print(msg)
def main():
load_dotenv(ROOT / ".env")
api_key = os.getenv("OWM_API_KEY")
city = os.getenv("CITY", "Taipei")
units = os.getenv("UNITS", "metric") # metric=°C, imperial=°F
lang = os.getenv("LANG", "zh_tw")
if not api_key:
log("找不到 OWM_API_KEY,請在 .env 設定。")
sys.exit(1)
params = {"q": city, "appid": api_key, "units": units, "lang": lang}
try:
r = requests.get(API, params=params, timeout=15)
if r.status_code == 401:
log("401 Unauthorized:金鑰錯誤或尚未啟用")
sys.exit(1)
r.raise_for_status()
data = r.json()
except requests.exceptions.RequestException as e:
log(f"API 失敗:{e}")
sys.exit(1)
row = {
"timestamp": datetime.now().isoformat(timespec="seconds"),
"city": data.get("name") or city,
"temp_c": (data.get("main") or {}).get("temp"),
"feels_like_c": (data.get("main") or {}).get("feels_like"),
"humidity": (data.get("main") or {}).get("humidity"),
"weather": ((data.get("weather") or [{}])[0]).get("description"),
"source": "OpenWeatherMap"
}
OUT_DIR.mkdir(parents=True, exist_ok=True)
newfile = not CSV_PATH.exists()
with open(CSV_PATH, "a", newline="", encoding="utf-8-sig") as f:
w = csv.DictWriter(f, fieldnames=list(row.keys()))
if newfile:
w.writeheader()
w.writerow(row)
log(f"已寫入 {CSV_PATH.name}:{row['city']} {row['temp_c']}°C,{row['weather']}")
if __name__ == "__main__":
main()
步驟 2:測試程式是否能正常執行
在終端機中輸入:
python day25_fetch_weather.py
執行結果:
已寫入 weather_log.csv:Taipei 29.23°C,晴
代表已成功抓到資料並存檔。
檔案會自動建立在 output/
資料夾。
步驟 3:使用 Python schedule 自動執行
建立 day25_scheduler.py
這支程式會每天在指定時間自動呼叫前面的抓資料腳本:
import time
import schedule
from subprocess import run
from pathlib import Path
ROOT = Path(__file__).resolve().parent
def job():
run(["python", str(ROOT / "day25_fetch_weather.py")], check=False)
schedule.every().day.at("09:00").do(job)
print("排程啟動中,每天 09:00 自動抓資料。按 Ctrl+C 可停止。")
while True:
schedule.run_pending()
time.sleep(1)
如果要測試的話可以先改成:
schedule.every(1).minutes.do(job)
這樣就能每分鐘自動跑一次觀察效果。
步驟 4:設定系統層級排程
由於我使用 Windows,以下以 Windows 的設定為例。
建立 run_weather.bat
:
@echo off
cd /d C:\Users\Alice\day25
call .\.venv\Scripts\activate.bat
python day25_fetch_weather.py >> logs\task.log 2>&1
再用 PowerShell 建立排程任務:
schtasks /Create /SC DAILY /ST 09:00 /TN "Day25 Weather Fetch" /TR "C:\Users\Alice\day25\run_weather.bat"
步驟 5:確認排程是否生效
我們需要觀察:
output/weather_log.csv
是否每天新增一列
logs/day25.log
是否有新紀錄
若有出錯,需要確認 API 金鑰、路徑與時間設定。
今天我學會了如何讓 Python 程式自動執行,透過排程每天自動抓取一次 API 資料。我了解了兩種常見的方法:一種是使用 Python 的第三方套件 schedule,讓程式在背景持續運行,並在指定時間自動執行任務;另一種是利用作業系統提供的排程功能,例如 Windows 工作排程器,來定時自動呼叫程式。這樣設定之後,我就不需要每天手動啟動程式,電腦會自己完成資料收集,讓工作更加有效率,也顯得更專業。