2026年1月16日 星期五

Gemini CLI 學習筆記 : 郵遞區號查詢小幫手專案 (一)

本篇旨在以使用 https://zip5.5432.tw 的 API 查詢郵遞區號為例來說明一個文組出身的程式小白如何透過 Gemini CLI 介面利用 Vibe coding 方式用嘴寫程式. 此網站可線上輸入地址來查詢郵遞區號, 也有提供 API 讓應用程式查詢, 此範例出自旗標 "Claude Code Vibe Coding 開發手冊" 這本書的第二章, 此處只是將 AI 工具改換成 Gemini CLI 而已 : 




此書範例程式碼與提示詞可在 GitHub 取得 :


本系列之前的文章參考 :


先摘要整理一下安裝 Gemin CLI 的步驟, Gemin CLI 必須在 Node.js 18 版以上才能跑, 首先開啟一個 Power Shell 視窗, 先安裝套件管理工具 Scoop :

PS C:\Users\tony1> Invoke-RestMethod -Uri https://get.scoop.sh | Invoke-Expression   

在 Windows 中使用 Scoop 來安裝 nvm 不僅可簡化安裝過程, 省去手動下載和配置的麻煩, 還可集中管理軟體與提高相容性. 

接著用 Scoop 安裝 Node.js 版本管理工具 nvm : 

PS C:\Users\tony1> scoop install nvm     

然後用 nvm 安裝 Node.js :

PS C:\Users\tony1> nvm install node   

安裝 Node.js 時會同時安裝 Node.js 的套件管理工具 npm, 最後用 npm 來安裝 Gemini CLI (是一個 Node.js 套件包) :

PS C:\Users\tony1> npm install -g @google/gemini-cli    

安裝好 Gemini CLI 後就可以馬上 "動口" 做 Vive coding, 用嘴來寫程式了. 

程式小白只要懂基本電腦操作 (其實就是常用的 DOS 檔案管理指令例如 mkdir/cd/del 等等),  即使是文組出身的人也可以快速開發出自己想要的軟體作品. 


1. 建立專案目錄 : 

首先在 Power shell 視窗中建立一個 gemini 資料夾來放置所有 Gemini CLI 專案 : 

PS C:\Users\tony1> d:   
PS D:\> mkdir gemini   

    目錄: D:\

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----       2026/1/13  上午 09:36                gemini

切換到 gemini 資料夾下建立一個 "postal-helper-proj1" 專案資料夾 : 

PS D:\> cd gemini   
PS D:\gemini> mkdir postal-helper-proj1   

    目錄: D:\gemini

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----       2026/1/13  上午 09:39                postal-helper-proj1

切換到專案目錄下 :

PS D:\gemini> cd postal-helper-proj1   
PS D:\gemini\postal-helper-proj1>  


2. 用 Google 帳號登入 Gemini CLI : 

在專案目錄下輸入 gemini 啟動 Gemini CLI : 

PS D:\gemini\postal-helper-proj1>gemini   




接下來就可輸入提示詞請 Gemini CLI 幫我們寫軟體了, 在旗標 "Claude Code Vibe Coding 開發手冊" 這本書 GitHub 資源的第二章可以找到提示詞 :


複製提示詞貼到 Gemini CLI 提示號後面按 Enter :

> 請用Python寫一個可以在命令列執行的郵遞區號小幫手,輸入是地址,輸出是 6 碼郵遞區號,台灣地址郵遞區號查詢程式使用 zip5.5432.tw API 查詢地址對應的郵遞區號

這時 Gemini CLI 會去讀取專案目錄, 發現裡面空空如也, 先顯示 Directory is empty 訊息後, 輸出如下訊息表示會寫一個 Python 程式利用 zip5.5432.tw 的 API (http://zip5.5432.tw/zip5json.py?adrs=地址) 來查詢給定地址之 6 碼郵遞區號, 寫好程式碼之後會先顯示, 並徵求允許將程式碼寫入專案目錄下的 postal_helper.py 檔案裡 (這檔名是它自訂的, 我們也可以在提示詞中指定) :

✦ I will create a Python script postal_helper.py that uses the zip5.5432.tw API to query the 6-digit postal code for a given address.




在程式碼後面會問 Apply this change? 我們可以直接按 Enter 選擇預設的 1. Allow once (每次寫入會詢問), 或按向下鍵移到 2. Allow for this session (本對話之後都不會再詢問, 直接寫入), 為了慎重起見, 用預設 1 即可. 

程式檔寫入完成後, Gemini CLI 輸出如下資訊, 表示它會用一個地址來測試這的程式看看是否能輸出正確的郵遞區號 : 

✦ I will now test the script with the address "台北市信義區市府路1號" (Taipei City Hall) to ensure it works correctly.

一樣直接按 Enter 選預設的 1. Allow once : 




查詢結果郵遞區號 11024 是正確的 : 




但它發現程式碼在處理中文輸出時出現怪碼 (可能是 UTF-8 編碼問題), 它立即自動更新程式碼, 並要求寫入檔案, 直接按 Enter 選預設的 1. Allow once : 




寫入後要求允許執行程式來測試是否繁體中文輸出 : 




雖然看起來似乎還是輸出怪碼, 但它卻回覆已解決此問題 :




另開一個命令提示字元或 PS 視窗, 切換到專案目錄下, 執行此 Python 程式 :

D:\gemini\postal-helper-proj1>dir   
 Volume in drive D is 新增磁碟區
 Volume Serial Number is 1258-16B8

 Directory of D:\gemini\postal-helper-proj1   

2026/01/16  下午 01:06    <DIR>          .
2026/01/13  上午 09:39    <DIR>          ..
2026/01/16  下午 02:16             2,924 postal_helper.py
               1 File(s)          2,924 bytes
               2 Dir(s)  934,934,114,304 bytes free

D:\gemini\postal-helper-proj1>python postal_helper.py 台北市信義區市府路1號   
正在查詢地址: 台北市信義區市府路1號 ...
------------------------------
地址: 台北市信義區市府路1號
6碼郵遞區號: 110204
------------------------------

果然能正確顯示繁體中文與輸出正確郵遞區號. 

以上我們只出一張嘴, 靠提示詞就讓 Gemini CLI 幫我們寫好可正確運行的程式, 從撰寫到測試 Gemini CLI 一手包辦, 我們連原始碼都還未一賭全貌, 好奇到底長怎樣的話, 可以用記事本開啟專案目錄下的 postal_helper.py 來看看 :

import sys
import json
import urllib.parse
import urllib.request
import io

# 確保在 Windows 上輸出為 UTF-8,避免亂碼
if sys.platform == "win32":
    sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
    sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8')

def get_postal_code(address):
    base_url = "https://zip5.5432.tw/zip5json.py"
    params = {'adrs': address}
    # Ensure the URL is correctly encoded
    url = f"{base_url}?{urllib.parse.urlencode(params)}"
    
    try:
        # User requested 6-digit postal code
        print(f"正在查詢地址: {address} ...")
        
        req = urllib.request.Request(url)
        # Some APIs require a User-Agent
        req.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) PostalHelper/1.0')
        
        with urllib.request.urlopen(req) as response:
            if response.status != 200:
                print(f"錯誤: API 返回狀態碼 {response.status}")
                return

            data = response.read()
            try:
                result = json.loads(data)
            except json.JSONDecodeError:
                print("錯誤: 無法解析 JSON 回應。")
                print(f"回應內容: {data.decode('utf-8', errors='ignore')}")
                return
            
            # The API returns 'zipcode6' for the 6-digit code.
            # Sometimes it might return an empty string or null if not found.
            zip6 = result.get('zipcode6')
            
            if zip6:
                print("-" * 30)
                print(f"地址: {result.get('address', address)}")
                print(f"6碼郵遞區號: {zip6}")
                print("-" * 30)
            else:
                print("找不到該地址的 6 碼郵遞區號。")
                # Show full result just in case useful info is elsewhere
                if 'error' in result:
                    print(f"API 錯誤: {result['error']}")

    except urllib.error.URLError as e:
        print(f"網絡錯誤: {e}")
    except Exception as e:
        print(f"發生未預期的錯誤: {e}")

if __name__ == "__main__":
    if len(sys.argv) > 1:
        # Join arguments to handle addresses with spaces if not quoted
        address_input = " ".join(sys.argv[1:])
        get_postal_code(address_input)
    else:
        # Interactive mode
        print("台灣 6 碼郵遞區號小幫手")
        print("用法: python postal_helper.py <地址>")
        print("或在下方輸入地址 (按 Ctrl+C 離開):")
        while True:
            try:
                address_input = input("\n請輸入地址: ").strip()
                if not address_input:
                    continue
                get_postal_code(address_input)
            except KeyboardInterrupt:
                print("\n程式結束。")
                break
            except EOFError:
                break

程式小白欣賞就好, 但對常寫 Python 程式的我來說, 這可能要花我半天才能搞定, 而且 AI 採用的實作方法會與我自行撰寫的大異其趣. 

沒有留言 :