【ก็อปวางแล้วรันได้เลย】มาสร้างแอป CLI พยากรณ์อากาศด้วย Python และ API กันเถอะ! คำแนะนำทีละขั้นตอนสำหรับมือใหม่
「เริ่มเขียนโปรแกรมแล้ว แต่ไม่รู้จะสร้างอะไรดี...」 「กำลังเรียนอยู่ แต่รู้สึกท้อใจเพราะสร้างสิ่งที่ใช้งานได้จริงไม่ได้สักที...」
เมื่อไม่กี่เดือนก่อน ผมก็เคยมีความกังวลแบบเดียวกันนี้เลยครับ ผมเริ่มเรียนรู้ด้วยตัวเองจากศูนย์โดยอาศัยความช่วยเหลือจาก AI และตอนนี้ผมก็สามารถบริหารจัดการเว็บไซต์ของตัวเองได้แล้ว แต่สิ่งที่ผมรู้สึกว่าสำคัญที่สุดในช่วงเริ่มต้นของการเรียนรู้ก็คือ 「ประสบการณ์ในการลงมือสร้างอะไรสักอย่างด้วยตัวเองและเห็นมันทำงานได้จริง」 ครับ
ในบทความนี้ ผมจะอธิบายวิธีสร้างแอปพลิเคชันบรรทัดคำสั่ง (CLI) ง่ายๆ ด้วย Python ที่สามารถบอกพยากรณ์อากาศได้ อย่างละเอียดที่สุด เพื่อให้โปรแกรมเมอร์มือใหม่ได้สัมผัสกับความรู้สึกที่ว่า "มันทำงานได้แล้ว! สนุกจัง!"
หน้าตาของแอปที่เสร็จแล้วจะเป็นแบบนี้ครับ เมื่อพิมพ์คำสั่งในเทอร์มินัล (หน้าจอสีดำ)...?
$ python weather.py Tokyo
[ สภาพอากาศในโตเกียว (JP) ]
สภาพอากาศ: ท้องฟ้าแจ่มใส ☀️
อุณหภูมิ: 28.5℃ (รู้สึกเหมือน: 29.1℃)
ความชื้น: 65%
ความเร็วลม: 3.1 m/s
ไม่มีอะไรซับซ้อนเลยครับ! แค่คัดลอกและวางโค้ดนี้ลงในคอมพิวเตอร์ของคุณ ก็สามารถใช้งานได้ทันที ผมจะแบ่งปันจุดที่ผมเคยติดขัดจริงๆ ไปพร้อมๆ กัน ดังนั้นไม่ต้องกังวลและทำตามไปได้เลยครับ
ขั้นตอนที่ 1: เตรียมตัวให้พร้อมสำหรับการผจญภัย! - การขอรับคีย์ API สภาพอากาศ
ก่อนอื่นเลย เราจะไปเอาข้อมูลสภาพอากาศมาจากไหน? พยากรณ์อากาศที่เราเห็นในทีวีหรือบนสมาร์ทโฟนก็มาจากข้อมูลที่หน่วยงานเฉพาะทางอย่างกรมอุตุนิยมวิทยาสังเกตการณ์มาใช่ไหมครับ
ในครั้งนี้ เราจะใช้บริการที่ชื่อว่า OpenWeatherMap ครับ การใช้กลไกที่เรียกว่า API ที่บริการนี้มีให้ จะทำให้เราสามารถดึงข้อมูลสภาพอากาศจากทั่วทุกมุมโลกมาใช้ในโปรแกรมของเราได้อย่างอิสระ
ไม่จำเป็นต้องคิดมากว่า "API คืออะไร?" ครับ ตอนนี้ให้คิดว่ามันเป็นเหมือน "รหัสผ่าน (กุญแจ) สำหรับการดึงข้อมูลสภาพอากาศจากโปรแกรม" ไปก่อน ผมจะอธิบายขั้นตอนการขอรับกุญแจ (API Key) นี้ให้ครับ
- เข้าไปที่ หน้า API ของ OpenWeatherMap แล้วคลิกที่ปุ่ม "Subscribe" ใต้ "Current Weather Data"
- กดปุ่ม "Get API key" ในแผนบริการฟรี แล้วสร้างบัญชี (ตั้งค่าอีเมลและรหัสผ่าน)
- เมื่อลงทะเบียนเสร็จสิ้น API Key เฉพาะของคุณจะถูกสร้างขึ้นในแท็บ "API keys" บนแดชบอร์ดของคุณ สตริงตัวอักษรและตัวเลขประมาณ 32 ตัวนี้คือ "รหัสผ่าน" ที่ผมได้อธิบายไปก่อนหน้านี้ครับ
【สำคัญมาก】ห้ามบอก API Key ของคุณให้ใครรู้ หรือนำไปเผยแพร่บนโซเชียลมีเดียหรือ GitHub เด็ดขาด!
คีย์นี้เป็นของคุณโดยเฉพาะ หากคนที่มีเจตนาร้ายรู้เข้า พวกเขาสามารถนำไปใช้เข้าถึงข้อมูลจำนวนมากอย่างผิดกฎหมาย และคุณอาจถูกเรียกเก็บเงินได้ ควรเก็บรักษาให้ดีเหมือนกุญแจบ้านของคุณเลยครับ
ขั้นตอนที่ 2: เตรียมเครื่องมือที่จำเป็น! - ไลบรารี `requests`
เมื่อได้ API Key มาแล้ว ขั้นตอนต่อไปคือการเตรียมเครื่องมือสำหรับใช้ API จาก Python นั่นคือไลบรารีที่ชื่อว่า `requests` ครับ
ไลบรารีก็เหมือนกับ "กล่องเครื่องมือ" ที่มีฟังก์ชันที่มีประโยชน์จัดเตรียมไว้ให้แล้ว ด้วย `requests` เราสามารถเข้าถึงเว็บไซต์และ API ได้ด้วยโค้ดเพียงไม่กี่บรรทัด
เปิดเทอร์มินัลบนคอมพิวเตอร์ของคุณ (Command Prompt หรือ PowerShell บน Windows, Terminal บน Mac) แล้วรันคำสั่งต่อไปนี้ครับ
pip install requests
หากมีข้อความ `Successfully installed...` ปรากฏขึ้น แสดงว่าสำเร็จแล้วครับ! ตอนนี้เราพร้อมที่จะสื่อสารกับ API สภาพอากาศแล้ว!
ขั้นตอนที่ 3: มาลองรันอะไรง่ายๆ กันก่อน!
ถึงเวลาเขียนโค้ดแล้วครับ ก่อนอื่น มาเขียนโค้ดง่ายๆ เพื่อดึงข้อมูลสภาพอากาศของเมืองที่ระบุ (ในที่นี้คือโตเกียว) กันก่อน สร้างไฟล์ชื่อ `weather.py` ในเอดิเตอร์ของคุณแล้ววางโค้ดต่อไปนี้ลงไปครับ
import requests
import json
# กรุณาแทนที่ด้วย API คีย์ของคุณที่ได้รับในขั้นตอนที่ 1
API_KEY = "วางAPIคีย์ของคุณที่นี่"
CITY_NAME = "Tokyo"
# สร้าง URL สำหรับส่งคำขอ API
api_url = f"https://api.openweathermap.org/data/2.5/weather?q={CITY_NAME}&appid={API_KEY}&units=metric&lang=th"
try:
# ส่งคำขอไปยัง API จริงๆ
response = requests.get(api_url)
response.raise_for_status() # หากมีข้อผิดพลาด ให้โยน exception
# แปลงผลลัพธ์จากรูปแบบ JSON เป็น dictionary ของ Python
data = response.json()
# แสดงข้อมูลเพื่อให้ดูง่าย
print(json.dumps(data, indent=2, ensure_ascii=False))
except requests.exceptions.RequestException as e:
print(f"เกิดข้อผิดพลาดในการสื่อสาร: {e}")
except Exception as e:
print(f"เกิดข้อผิดพลาดที่ไม่คาดคิด: {e}")
หลังจากวางโค้ดแล้ว อย่าลืมเปลี่ยนส่วน `API_KEY = "วางAPIคีย์ของคุณที่นี่"` ให้เป็น API Key ของคุณเองที่ได้รับมาก่อนหน้านี้นะครับ
เมื่อเปลี่ยนแล้ว ลองรันไฟล์นี้ในเทอร์มินัลดูครับ
$ python weather.py
เป็นอย่างไรบ้างครับ? หากมีข้อความ (ข้อมูล) จำนวนมากแสดงขึ้นมาแบบนี้ แสดงว่าสำเร็จแล้ว!
{
"coord": {
"lon": 139.6917,
"lat": 35.6895
},
"weather": [
{
"id": 800,
"main": "Clear",
"description": "ท้องฟ้าแจ่มใส",
"icon": "01d"
}
],
"base": "stations",
"main": {
"temp": 28.5,
"feels_like": 29.1,
"temp_min": 27.21,
"temp_max": 29.58,
"pressure": 1012,
"humidity": 65
},
"visibility": 10000,
"wind": {
"speed": 3.09,
"deg": 190
},
// ...และอื่นๆ อีกมากมาย
}
นี่คือข้อมูลสภาพอากาศปัจจุบันของโตเกียวในรูปแบบดิบที่ส่งมาจาก OpenWeatherMap ครับ ขั้นตอนต่อไปคือการดึงเฉพาะข้อมูลที่จำเป็นออกจากข้อมูลในรูปแบบที่เรียกว่า JSON นี้
【อธิบายจุดที่อาจทำให้สับสน】วิธีการอ่านข้อมูล JSON
JSON ประกอบด้วยการผสมผสานระหว่าง `{}` (วงเล็บปีกกา) และ `[]` (วงเล็บเหลี่ยม)
- `{}`: แทน พจนานุกรม (อ็อบเจกต์) ซึ่งเป็นคู่ของ "คีย์" และ "ค่า" ตัวอย่างเช่น `"temp": 28.5` หมายความว่า "คีย์ 'temp' มีค่าเท่ากับ 28.5"
- `[]`: แทน รายการ (อาร์เรย์) ซึ่งเป็นข้อมูลหลายๆ ตัวเรียงกันเป็นลำดับ
ขั้นตอนที่ 4: มาปรับปรุงแอปให้เจ๋งขึ้นกันเถอะ!
จากนี้ไปคือของจริงครับ แทนที่จะต้องแก้ไขโค้ดทุกครั้ง เราจะพัฒนาแอปให้เป็นรูปแบบ CLI ที่แท้จริง โดยให้ผู้ใช้สามารถป้อนชื่อเมืองได้ และแสดงเฉพาะข้อมูลที่จำเป็นอย่างชัดเจน
ในครั้งนี้ เพื่อสร้างแอป CLI ที่จริงจังยิ่งขึ้น เราจะใช้ไลบรารีมาตรฐานของ Python ที่ชื่อว่า `argparse` ซึ่งจะช่วยให้เราสามารถส่งข้อมูลขณะรันโปรแกรมได้ เช่น `python weather.py Bangkok`
กรุณาแทนที่เนื้อหาทั้งหมดในไฟล์ `weather.py` ด้วยโค้ดด้านล่างนี้ครับ วิธีการจัดการ API Key ก็ถูกเปลี่ยนให้ปลอดภัยยิ่งขึ้นด้วย
import requests
import argparse
import os
def get_weather_emoji(weather_main):
"""คืนค่าอีโมจิจากชื่อสภาพอากาศภาษาอังกฤษ"""
if weather_main == "Clear":
return "☀️"
elif weather_main == "Clouds":
return "☁️"
elif weather_main == "Rain":
return "🌧️"
elif weather_main == "Drizzle":
return "🌦️"
elif weather_main == "Thunderstorm":
return "⛈️"
elif weather_main == "Snow":
return "❄️"
else:
return "🌫️" # Mist, Smoke, Haze, Dust, Fog, Sand, Ash, Squall, Tornado
def format_weather_data(data):
"""จัดรูปแบบการตอบกลับของ API และคืนค่าเป็นสตริง"""
try:
city_name = data["name"]
country = data["sys"]["country"]
weather_description = data["weather"][0]["description"]
weather_main = data["weather"][0]["main"]
emoji = get_weather_emoji(weather_main)
temp = data["main"]["temp"]
feels_like = data["main"]["feels_like"]
humidity = data["main"]["humidity"]
wind_speed = data["wind"]["speed"]
# สร้างสตริงผลลัพธ์เพื่อให้ดูง่าย
output = f"[ สภาพอากาศใน {city_name} ({country}) ]\n"
output += f"สภาพอากาศ: {weather_description} {emoji}\n"
output += f"อุณหภูมิ: {temp}°C (รู้สึกเหมือน: {feels_like}°C)\n"
output += f"ความชื้น: {humidity}%\n"
output += f"ความเร็วลม: {wind_speed} m/s"
return output
except KeyError:
return "การแยกวิเคราะห์ข้อมูลสภาพอากาศล้มเหลว รูปแบบการตอบกลับอาจไม่ถูกต้อง"
def main():
# 1. รับ API key จากตัวแปรสภาพแวดล้อม
# เพื่อการจัดการคีย์ที่ปลอดภัยยิ่งขึ้น
api_key = os.getenv("OPENWEATHERMAP_API_KEY")
if not api_key:
print("ข้อผิดพลาด: ไม่ได้ตั้งค่าตัวแปรสภาพแวดล้อม 'OPENWEATHERMAP_API_KEY'")
print("กรุณาตั้งค่า API key แล้วลองอีกครั้ง")
return # ออกจากโปรแกรม
# 2. ตั้งค่าอาร์กิวเมนต์ของบรรทัดคำสั่ง
parser = argparse.ArgumentParser(description="แสดงข้อมูลสภาพอากาศปัจจุบันของเมืองที่ระบุ")
parser.add_argument("city", help="ชื่อเมืองที่ต้องการข้อมูลสภาพอากาศ (เช่น Bangkok)")
parser.add_argument("-u", "--units", choices=["metric", "imperial"], default="metric",
help="ระบุหน่วยของอุณหภูมิ ('metric' สำหรับเซลเซียส, 'imperial' สำหรับฟาเรนไฮต์)")
args = parser.parse_args()
# 3. ส่งคำขอไปยัง API
base_url = "https://api.openweathermap.org/data/2.5/weather"
params = {
"q": args.city,
"appid": api_key,
"units": args.units,
"lang": "th"
}
try:
response = requests.get(base_url, params=params)
# โยน exception สำหรับรหัสข้อผิดพลาด 4xx, 5xx
response.raise_for_status()
weather_data = response.json()
# 4. แสดงผลลัพธ์
formatted_output = format_weather_data(weather_data)
print(formatted_output)
except requests.exceptions.HTTPError as e:
if e.response.status_code == 401:
print("ข้อผิดพลาด: API key ไม่ถูกต้อง กรุณาตรวจสอบว่าได้ตั้งค่า API key ที่ถูกต้องแล้ว")
elif e.response.status_code == 404:
print(f"ข้อผิดพลาด: ไม่พบเมือง '{args.city}' กรุณาตรวจสอบชื่อเมือง")
else:
print(f"เกิดข้อผิดพลาด HTTP: {e}")
except requests.exceptions.RequestException as e:
print(f"เกิดข้อผิดพลาดในการสื่อสาร: {e}")
except Exception as e:
print(f"เกิดข้อผิดพลาดที่ไม่คาดคิด: {e}")
if __name__ == "__main__":
main()
【สำคัญ】วิธีการตั้งค่า API Key อย่างปลอดภัย (ตัวแปรสภาพแวดล้อม)
ผมได้บอกไปแล้วว่าการเขียน API Key ลงในโค้ดโดยตรงนั้นอันตราย ดังนั้นเราจะใช้กลไกที่เรียกว่า "ตัวแปรสภาพแวดล้อม" ซึ่งใช้กันในระดับมืออาชีพด้วย เป็นวิธีการให้คอมพิวเตอร์ของเราจดจำ API Key ไว้
สำหรับ Mac / Linux:
export OPENWEATHERMAP_API_KEY="API_Key_ของคุณ"
สำหรับ Windows (Command Prompt):
set OPENWEATHERMAP_API_KEY="API_Key_ของคุณ"
สำหรับ Windows (PowerShell):
$Env:OPENWEATHERMAP_API_KEY="API_Key_ของคุณ"
รันคำสั่งด้านบนในเทอร์มินัลของคุณ (การตั้งค่าจะถูกรีเซ็ตเมื่อปิดเทอร์มินัล) ด้วยวิธีนี้ โค้ด `os.getenv("OPENWEATHERMAP_API_KEY")` จะสามารถอ่านคีย์ที่คุณตั้งค่าไว้ในคอมพิวเตอร์ได้
เมื่อพร้อมแล้ว ก็มารันกันเลย!
$ python weather.py "Chiang Mai"
สภาพอากาศของเชียงใหม่แสดงขึ้นมาอย่างสวยงามใช่ไหมครับ?
คราวนี้ มาลองแสดงสภาพอากาศของกรุงเทพฯ ในหน่วยฟาเรนไฮต์กันดูบ้าง
$ python weather.py Bangkok -u imperial
อย่าลืมใส่ `"` (เครื่องหมายคำพูดคู่) คร่อมชื่อเมืองหากมีช่องว่างนะครับ หากอุณหภูมิแสดงเป็นฟาเรนไฮต์ (°F) แสดงว่าสำเร็จ!
ลองจงใจป้อนชื่อเมืองที่ผิด หรือตั้งค่า API Key ผิดๆ เพื่อดูว่าข้อความแสดงข้อผิดพลาดจะปรากฏขึ้นอย่างถูกต้องหรือไม่ นี่คือ "การจัดการข้อผิดพลาดที่แข็งแกร่ง" ครับ
สรุป: ก้าวต่อไปหลังจาก "มันทำงานได้แล้ว!"
เยี่ยมมากครับ! ตอนนี้แอปพยากรณ์อากาศ CLI ของคุณเองก็เสร็จสมบูรณ์แล้ว นอกจากการคัดลอกและวางโค้ดแล้ว คุณน่าจะได้เรียนรู้สิ่งต่างๆ ต่อไปนี้ด้วย:
- วิธีดึงข้อมูลจากภายนอกโดยใช้ API (`requests`)
- วิธีจัดการข้อมูลในรูปแบบ JSON
- วิธีจัดการ API Key อย่างปลอดภัย (ตัวแปรสภาพแวดล้อม)
- วิธีสร้างอาร์กิวเมนต์สำหรับแอป CLI อย่างจริงจัง (`argparse`)
- วิธีสร้างโปรแกรมที่เป็นมิตรและไม่หยุดทำงานเมื่อเกิดข้อผิดพลาด (`try-except`)
- การจัดระเบียบโค้ดโดยใช้ฟังก์ชัน
การเรียนเขียนโปรแกรมนั้น การสะสม "ความสำเร็จเล็กๆ น้อยๆ" เหล่านี้เป็นสิ่งสำคัญที่สุด ลองใช้แอปที่คุณสร้างขึ้นในวันนี้เป็นพื้นฐาน แล้วดัดแปลงด้วยไอเดียของคุณเอง เช่น "คราวหน้าลองแสดงสภาพอากาศหลายๆ เมืองพร้อมกันดีกว่า" "ลองเพิ่มพยากรณ์อากาศรายชั่วโมงดู" หรือ "ลองส่งผลลัพธ์ไปที่ LINE ดู" เป็นต้น
ใช้ "ความสนุกในการสร้างสิ่งที่ทำงานได้" เป็นเชื้อเพลิง แล้วมาผจญภัยในโลกของการเขียนโปรแกรมกันต่อไปเถอะครับ!
ก้าวต่อไป
ในการเขียนโปรแกรม Python ทุกคนต้องเคยเจอกับ "ข้อผิดพลาดในการเยื้อง" (Indentation Error) ลองอ่านบทความของเราที่อธิบายอย่างละเอียดว่าทำไมมันถึงเกิดขึ้นและจะแก้ไขได้อย่างไร
สาเหตุและวิธีแก้ไข IndentationError