Narwhal API 索引了 1,489 個採用 CC BY 4.0 授權的世界銀行 WDI 年度指標。若要在 Python 中取得世界銀行資料,請搜尋指標、在其 ID 範本中加入小寫國家代碼,再使用 API 金鑰請求觀測資料。回應包含期間、十進位字串數值、來源標示及授權網址。方案會決定可存取的歷史期間,以及每日未快取資料擷取額度。
使用 API
- 取得免費金鑰並準備 Python 環境 在註冊頁面建立帳號、取得 API 金鑰,並在執行 Python 的 shell 中設定
NARWHAL_API_KEY。請將預留位置替換為你的金鑰。安裝用於 HTTP 呼叫的requests,以及用於 DataFrame 的pandas。每次請求都在 Authorization 標頭中使用金鑰;最後一步的完整程式會從環境中讀取金鑰。python -m pip install requests pandas export NARWHAL_API_KEY="replace-with-your-key" - 搜尋指標 使用
source=wdi在目錄中搜尋gdp per capita。印出每筆結果的id_template與標題,再選擇需要的指標。所有方案皆可使用目錄搜尋,且不會呼叫來源。params引數會處理搜尋詞中的空格。搜尋結果描述的是指標;國家應放在下一步建立的序列 ID 中。import os import requests BASE_URL = "https://api.narwhalapi.com" headers = { "Authorization": f"Bearer {os.environ['NARWHAL_API_KEY']}" } response = requests.get( f"{BASE_URL}/v1/economics/catalogue", headers=headers, params={"q": "gdp per capita", "source": "wdi"}, timeout=10, ) response.raise_for_status() catalogue = response.json() for hit in catalogue["results"]: print(hit["id_template"], hit["title"]) - 在範本中加入國家 將所選範本中的
{country}替換為小寫 ISO 3166-1 alpha-3 代碼。印尼使用idn。世界銀行 ID 的格式為wdi:<indicator>/<iso3>,包含指標與國家之間的斜線。透過id查詢參數傳入完整 ID。此程式片段會選取第一筆搜尋結果;使用前請先檢查印出的標題。if not catalogue["results"]: raise SystemExit("No matching indicators found.") selected = catalogue["results"][0] series_id = selected["id_template"].replace("{country}", "idn") print(series_id) - 讀取年度觀測資料 請求該 ID 的觀測資料。年度期間使用
YYYY;選填的start與end皆包含邊界。回應上限最多接受 1,000 筆觀測資料,預設為 100 筆。如果next_cursor有值,請將其作為cursor傳入以繼續讀取。提高上限不會延長方案可存取的歷史期間,缺漏年份也不會出現在回應中。response = requests.get( f"{BASE_URL}/v1/economics/catalogue/series/observations", headers=headers, params={"id": series_id, "limit": 1000}, timeout=10, ) response.raise_for_status() observations = response.json()["observations"] - 建立 DataFrame 使用觀測資料建立 DataFrame,將
period轉為整數,並將value轉為浮點數。數值以十進位字串回傳。需要十進位運算時,請使用Decimal取代float()。分析時請一併保留回應中的單位標籤:指標標題會說明數值衡量的內容。此轉換不會填補缺漏,也不會為缺漏年份建立觀測資料。import pandas as pd frame = pd.DataFrame(observations, columns=["period", "value"]) frame["period"] = frame["period"].astype(int) frame["value"] = frame["value"].map(float) print(frame) - 批次查詢多個國家並處理請求錯誤 執行這份完整程式,讀取範例中的 GDP 序列,並批次查詢印尼與加拿大的最新數值。以逗號串接 ID;最新資料端點接受 1 至 50 個不重複的 ID。每個回傳序列計入一次呼叫,並一次計入用量。程式會印出各國的期間與數值、列出缺漏的 ID,並在收到 400、404 或
429 fetch_limit_reached回應時顯示錯誤訊息並停止。import os import requests import pandas as pd BASE_URL = "https://api.narwhalapi.com" HEADERS = { "Authorization": f"Bearer {os.environ['NARWHAL_API_KEY']}" } def get_json(path, params): response = requests.get( f"{BASE_URL}{path}", headers=HEADERS, params=params, timeout=10, ) try: response.raise_for_status() except requests.HTTPError: problem = response.json() code = problem.get("code", "unknown_error") if response.status_code == 429 and code == "fetch_limit_reached": retry_after = response.headers.get("Retry-After") raise SystemExit( f"Uncached fetch allowance used. Retry-After: {retry_after}" ) if response.status_code in (400, 404): raise SystemExit(f"{code}: {problem.get('detail', '')}") raise return response.json() series_id = "wdi:ny.gdp.mktp.cd/idn" rows = [] params = {"id": series_id, "limit": 1000} while True: payload = get_json( "/v1/economics/catalogue/series/observations", params ) rows.extend(payload["observations"]) cursor = payload.get("next_cursor") if not cursor: break params["cursor"] = cursor frame = pd.DataFrame(rows, columns=["period", "value"]) frame["period"] = frame["period"].astype(int) frame["value"] = frame["value"].map(float) print(frame) countries = ("idn", "can") ids = [f"wdi:ny.gdp.mktp.cd/{country}" for country in countries] batch = get_json( "/v1/economics/catalogue/latest", {"ids": ",".join(ids)}, ) for observation in batch["observations"]: country = observation["id"].rsplit("/", 1)[1] print(country, observation["period"], observation["value"]) for missing in batch["missing"]: print("Missing:", missing)
如何解讀印尼 GDP 範例?
序列 wdi:ny.gdp.mktp.cd/idn 是以當期美元計價的印尼 GDP。在 27 October 2026 使用 Pro 金鑰並設定 limit=3 的請求,回傳了以下觀測資料。此範例使用 GDP 總額;若需要人均 GDP,請使用目錄搜尋取得的範本。
[
{"period": "1967", "value": "5667756627.92093"},
{"period": "1968", "value": "7076465299.81141"},
{"period": "1969", "value": "8337423312.88344"}
]對於 1967 年,float("5667756627.92093") 會轉換數值,供 DataFrame 進行數值運算。如果也需要其十進位表示,請保留原始字串。回應包含世界銀行 WDI 來源標示及 CC BY 4.0 授權網址。使用資料時,請一併保留來源標示與授權資訊。
為什麼我的 Free 金鑰只回傳幾年的資料?
Free 可存取最近 12 個月的歷史資料,年度資料則至少提供最新 5 筆觀測資料。Narwhal 會比較方案期間與此最低筆數,採用可提供較多觀測資料的規則。因此,即使大多數資料超出一般期間,年度序列仍會保留數筆觀測資料。年度最低筆數適用於所有方案。
我的方案適用哪個上限:
| 方案 | 每帳戶每日未快取擷取次數(UTC) | 歷史資料範圍 |
|---|---|---|
| 免費 | 10 | 最近 12 個月,且至少包含最新 5 筆年度觀測資料 |
| Basic | 100 | 最近 5 年,且至少包含最新 5 筆年度觀測資料 |
| Pro | 1,000 | 完整歷史資料 |
若整個查詢範圍都早於允許的期間,會回傳 403 plan_upgrade_required。對於年度序列,Narwhal 會在載入序列後檢查範圍,以納入最低筆數規則。請參閱方案詳細資訊,選擇符合分析需求的歷史期間。
429 fetch_limit_reached 錯誤代表什麼?
你的帳號已用完每日額度,而此請求需要擷取尚未快取的資料。重試前請先讀取 Retry-After;額度會在 00:00 UTC 重設。達到上限後,已快取的序列仍可回應。世界銀行資料的快取時間介於 24 小時至 7 天,因此再次請求不一定需要擷取資料。
遇到 400 invalid_series_id 時,請檢查指標、斜線及小寫國家代碼。400 invalid_query 表示查詢無效。404 not_found 可能表示索引中沒有該指標;Narwhal 會保留此結果 24 小時。再次請求前,請先將 ID 與目錄搜尋結果核對。
過期資料回應及 400、404、503 回應不計入用量。如果來源無法使用,且沒有快取副本,Narwhal 會回傳 503 upstream_busy,並附上 Retry-After。重試處理方式請參閱快取與 429 處理。
發布於 。
後續步驟
建立免費金鑰,從自己的程式碼呼叫 API。 取得免費 API 金鑰
