iT邦幫忙

2025 iThome 鐵人賽

DAY 16
0
Modern Web

每天一點 API:打造我的生活小工具系列 第 16

Day16 — API 資料轉換:JSON、CSV、Excel 一次搞懂

  • 分享至 

  • xImage
  •  

API 抓回來的資料通常是 JSON,可是實際工作時,很多時候需要把它轉成 CSV 或 Excel,才比較好查資料或分享給別人。

因此今天我就要來動手練習,把 JSON 轉成不同格式存起來。

為什麼要學資料轉換?

不同的工作需求會用到不同格式的資料。

  • JSON:程式設計師最常用,能表現複雜巢狀結構的資料,適合程式操作和系統間交換。

  • CSV:最輕量的格式,像純文字表格,很方便匯入許多分析工具。

  • Excel:給不懂程式的人用,非常友善。還支援更多功能,像是篩選、公式、圖表。

跨部門的溝通需求

  • 工程師可能要拿 JSON,方便用程式處理。

  • 分析師要 CSV,好用各種資料分析軟體。

  • 非技術背景的人可能愛用 Excel,因為它操作簡單、視覺化功能強。

提高資料重複利用性

  • 只有一份 API 取得的資料,轉成各種格式,能滿足不同部門不同需求。

  • 讓資料能更好、更方便被應用。

三種常見資料格式比較

JSON

  • 給系統或程式使用的格式

  • 支援巢狀和複雜結構

  • 不太適合用來做報表或直接看

CSV

  • 純文字的表格格式,資料用逗號隔開

  • 非常輕量,適合存簡單表格資料

  • 很適合快速匯入很多資料分析工具

Excel

  • 具備豐富格式,可以有顏色、公式、篩選等功能

  • 更適合人閱讀和進一步加工

  • 是非工程人員最喜歡使用的格式

小實作:從 API 抓資料並存成 CSV / JSON / Excel

步驟 1:準備開發環境

  • 先安裝好需要的套件:
pip install requests pandas openpyxl
  • 建立一個名為 day16_convert_formats.py 的 Python 檔案。

步驟 2:抓取 API 資料

  • 使用免費的 JSONPlaceholder API,抓取用戶資料。

  • 回傳的是 JSON 格式的清單。

import os, csv, json, argparse
from datetime import datetime
import requests

# 可重用的免費測試 API
API = "https://jsonplaceholder.typicode.com/users"
OUT_DIR = "output"

# 資料抓取
def fetch_users(timeout=10):
    r = requests.get(API, timeout=timeout)
    r.raise_for_status()
    return r.json()  # list[dict]

步驟 3:扁平化資料

  • 有巢狀的資料需要攤平成一層才能方便使用。

  • 例如從 address.city 抓出 city,從 company.name 抓出 company,保持結構簡單。

# 扁平化:把巢狀欄位攤平成一層 
def pick(d, path, default=""):
    cur = d
    for k in path.split("."):
        if isinstance(cur, dict) and k in cur:
            cur = cur[k]
        else:
            return default
    return cur

def flatten_user(u: dict) -> dict:
    return {
        "id": u.get("id"),
        "name": u.get("name",""),
        "username": u.get("username",""),
        "email": u.get("email",""),
        "city": pick(u, "address.city"),
        "zipcode": pick(u, "address.zipcode"),
        "phone": u.get("phone",""),
        "website": u.get("website",""),
        "company": pick(u, "company.name"),
    }

步驟 4:存成不同格式

  • 存 JSON:用 Python 的 json.dump()

  • 存 CSV:用 csv.DictWriter(),並加 utf-8-sig 解決 Excel 打開亂碼問題。

  • 存 Excel:用 pandas.DataFrame.to_excel()

# 檔名工具
def stamp():
    return datetime.now().strftime("%Y%m%d_%H%M%S")

# 輸出:JSON / CSV / XLSX 
def save_json(rows, path):
    os.makedirs(os.path.dirname(path), exist_ok=True)
    with open(path, "w", encoding="utf-8") as f:
        json.dump(rows, f, ensure_ascii=False, indent=2)
    print(f"JSON 已輸出:{path}({len(rows)} 筆)")

def save_csv(rows, path, fieldnames):
    os.makedirs(os.path.dirname(path), exist_ok=True)
    # 用 utf-8-sig 讓 Windows Excel 直接開不亂碼
    tmp = path + ".tmp"
    with open(tmp, "w", newline="", encoding="utf-8-sig") as f:
        w = csv.DictWriter(f, fieldnames=fieldnames)
        w.writeheader()
        w.writerows(rows)
    os.replace(tmp, path)
    print(f"CSV 已輸出:{path}({len(rows)} 筆)")

def save_xlsx(rows, path):
    try:
        import pandas as pd  # 需要 pandas + openpyxl
    except ImportError:
        print("未安裝 pandas/openpyxl,略過 XLSX 輸出。請先:pip install pandas openpyxl")
        return
    os.makedirs(os.path.dirname(path), exist_ok=True)
    df = pd.DataFrame(rows)
    df.to_excel(path, index=False)
    print(f"Excel 已輸出:{path}({len(rows)} 筆)")

步驟 5:測試與使用

  • 預設會輸出 JSON、CSV、Excel 三種格式。

  • 也可以指定只輸出其中一種格式。

  • 輸出檔案都會加上時間戳記,避免被覆蓋。

# 主流程 
def main():
    ap = argparse.ArgumentParser(description="API 資料轉換為 CSV / JSON / Excel")
    ap.add_argument("--fmt", choices=["json","csv","xlsx","all"], default="all",
                    help="輸出格式(預設 all)")
    ap.add_argument("--outdir", default=OUT_DIR, help="輸出資料夾(預設 output)")
    ap.add_argument("--timeout", type=float, default=10.0, help="API 逾時秒數(預設 10)")
    args = ap.parse_args()

    try:
        raw = fetch_users(timeout=args.timeout)
    except requests.exceptions.RequestException as e:
        print("API 失敗:", e)
        return

    rows = [flatten_user(u) for u in raw]
    fields = ["id","name","username","email","city","zipcode","phone","website","company"]
    ts = stamp()

    # 檔名(帶時間戳,避免覆蓋)
    json_path = os.path.join(args.outdir, f"users_{ts}.json")
    csv_path  = os.path.join(args.outdir, f"users_{ts}.csv")
    xlsx_path = os.path.join(args.outdir, f"users_{ts}.xlsx")

    # 依選擇輸出
    if args.fmt in ("json", "all"):
        save_json(rows, json_path)
    if args.fmt in ("csv", "all"):
        save_csv(rows, csv_path, fields)
    if args.fmt in ("xlsx", "all"):
        save_xlsx(rows, xlsx_path)

    print("完成!")

if __name__ == "__main__":
    main()

執行結果:

接著可以到 day16/output 的資料夾中找到剛剛輸出的三個檔案。

為什麼輸出的 CSV 是 Excel 分隔值檔案?

因為 Windows 會把 .csv 副檔名預設關聯到 Excel,檔案總管就用「Excel 分隔值檔案」當成中文名稱;但本質上它仍然是純文字的 CSV(逗號分隔),不是 Excel 的 .xlsx 活頁簿。

今日總結

  • 懂了 CSV 、 JSON 、 Excel 的使用情境與差異

  • 實作從 API 、 扁平化 、 輸出多種格式

  • 體驗了實務上「一份資料,多種格式」的工作流程


上一篇
Day15 — 從巢狀到平面:新聞 API 資料整理練習
下一篇
Day17 — 從數字到圖表:Python 資料視覺化基礎
系列文
每天一點 API:打造我的生活小工具17
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言