在 Day 7 我們設計了 Pipeline 架構,把「Database → Page → Block → JSON」的流程視覺化,並討論了增量更新、結構化輸出等重點。
今天,我們要實際寫程式,把前面 Day 5 與 Day 6 的成果串起來,讓 Pipeline 一次抓取多個 Database → 解析 Page → 清理 Block → 輸出 JSON。
data/clean/
。config/databases.yml
我們不再將 Database ID 寫死在 .env,而是新增一個設定檔 config/databases.yml,集中管理:
databases:
- id: "abcd1234efgh5678ijkl9012mnop3456"
name: "Life_BusanTravelPlan"
- id: "xyz1234abcd5678ijkl9012mnop3456"
name: "Learning_PythonBasicNotes"
⚙️ 小提醒:先安裝 pyyaml,以便讀取 .yml 檔
先安裝套件,在你的專案虛擬環境(venv)裡執行:pip install pyyaml
[.env + config/databases.yml]
│
▼
讀取 Token & DB 清單
│
▼
for 每個 Database
│
▼
/databases/{id}/query → 取得 rows (含 page_id)
│
▼
for 每個 page_id:
/blocks/{page_id}/children → 遞迴抓取 blocks
│
▼
parse_block() 統一結構
│
▼
以 db_name 分檔 → data/clean/{db}.json
.env
,不會硬編碼在程式裡src/run_pipeline.py
)
import os, json, requests, yaml
from dotenv import load_dotenv
from fetch_learning_database import query_database_all
from fetch_learning_page import fetch_page_blocks
from parse_learning_blocks import parse_block
load_dotenv()
TOKEN = os.getenv("NOTION_TOKEN")
HEADERS = {
"Authorization": f"Bearer {TOKEN}",
"Notion-Version": "2022-06-28"
}
BASE = "https://api.notion.com/v1"
def run_pipeline(config_path="config/databases.yml"):
with open(config_path, "r", encoding="utf-8") as f:
config = yaml.safe_load(f)
os.makedirs("data/clean", exist_ok=True)
for db in config["databases"]:
db_id = db["id"]
db_name = db["name"]
print(f"=== 處理 Database: {db_name} ===")
# Step 1: 抓 Database rows
rows = query_database_all(db_id)
print(f" Rows: {len(rows)}")
db_results = []
for row in rows:
page_id = row["id"]
# Step 2: 抓 Page blocks
blocks = fetch_page_blocks(page_id)
# Step 3: 解析 Block
parsed = [parse_block(b) for b in blocks]
db_results.append({
"db_name": db_name,
"db_id": db_id,
"page_id": page_id,
"blocks": parsed
})
# Step 4: 存成獨立檔案
safe_name = db_name.replace(" ", "_") # 避免空白或特殊字元
out_path = f"data/clean/{safe_name}.json"
with open(out_path, "w", encoding="utf-8") as f:
json.dump(db_results, f, ensure_ascii=False, indent=2)
print(f"Saved results for {db_name} → {out_path}")
if __name__ == "__main__":
run_pipeline()
data/clean/
├── Learning_PythonBasicNotes.json
└── Life_BusanTravelPlan.json
db_name
db_id
page_id
blocks
(展平後的內容)今天,我們把 Day 5 與 Day 6 的成果整合成 自動化 Pipeline,能一次抓取多個 Database,展開 Page 與 Block,並清理成統一格式的 JSON。這樣一來,我們的 Notion 知識就能被系統化抽取,不再需要手動 API 呼叫。
在 Day 9,我們將進一步設計 SQLite Schema,思考如何把這些 JSON 正規化存入資料庫,為後續的向量化(Embedding)與 RAG 知識庫打下基礎。