🇯🇵 日本語 | 🇺🇸 English | 🇪🇸 Español | 🇵🇹 Português | 🇹🇭 ไทย | 🇨🇳 中文

【ก็อปวางแล้วรันได้เลย】มาสร้างแอป 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) นี้ให้ครับ

  1. เข้าไปที่ หน้า API ของ OpenWeatherMap แล้วคลิกที่ปุ่ม "Subscribe" ใต้ "Current Weather Data"
  2. กดปุ่ม "Get API key" ในแผนบริการฟรี แล้วสร้างบัญชี (ตั้งค่าอีเมลและรหัสผ่าน)
  3. เมื่อลงทะเบียนเสร็จสิ้น 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 ประกอบด้วยการผสมผสานระหว่าง `{}` (วงเล็บปีกกา) และ `[]` (วงเล็บเหลี่ยม)

ใน Python, `{}` ของ JSON สามารถจัดการได้เหมือน "พจนานุกรม" และ `[]` เหมือน "รายการ" ทำให้เข้ากันได้ดีมาก ตัวอย่างเช่น หากคุณต้องการดึงข้อมูลอุณหภูมิ (`temp`) คุณสามารถเข้าถึง `temp` ที่อยู่ในกลุ่มใหญ่ที่ชื่อ `main` ได้โดยเขียนว่า `data['main']['temp']` ง่ายใช่ไหมล่ะ!

ขั้นตอนที่ 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 ของคุณเองก็เสร็จสมบูรณ์แล้ว นอกจากการคัดลอกและวางโค้ดแล้ว คุณน่าจะได้เรียนรู้สิ่งต่างๆ ต่อไปนี้ด้วย:

การเรียนเขียนโปรแกรมนั้น การสะสม "ความสำเร็จเล็กๆ น้อยๆ" เหล่านี้เป็นสิ่งสำคัญที่สุด ลองใช้แอปที่คุณสร้างขึ้นในวันนี้เป็นพื้นฐาน แล้วดัดแปลงด้วยไอเดียของคุณเอง เช่น "คราวหน้าลองแสดงสภาพอากาศหลายๆ เมืองพร้อมกันดีกว่า" "ลองเพิ่มพยากรณ์อากาศรายชั่วโมงดู" หรือ "ลองส่งผลลัพธ์ไปที่ LINE ดู" เป็นต้น

ใช้ "ความสนุกในการสร้างสิ่งที่ทำงานได้" เป็นเชื้อเพลิง แล้วมาผจญภัยในโลกของการเขียนโปรแกรมกันต่อไปเถอะครับ!

ก้าวต่อไป

ในการเขียนโปรแกรม Python ทุกคนต้องเคยเจอกับ "ข้อผิดพลาดในการเยื้อง" (Indentation Error) ลองอ่านบทความของเราที่อธิบายอย่างละเอียดว่าทำไมมันถึงเกิดขึ้นและจะแก้ไขได้อย่างไร

สาเหตุและวิธีแก้ไข IndentationError