🌟 Hello,我是蔣星熠Jaxonic!
🌈 在浩瀚無垠的技術宇宙中,我是一名執著的星際旅人,用代碼繪制探索的軌跡。
🚀 每一個算法都是我點燃的推進器,每一行代碼都是我航行的星圖。
🔭 每一次性能優化都是我的天文望遠鏡,每一次架構設計都是我的引力彈弓。
🎻 在數字世界的協奏曲中,我既是作曲家也是首席樂手。讓我們攜手,在二進制星河中譜寫屬于極客的壯麗詩篇!
摘要
作為一名多年沉浸在API開發與集成領域的技術探索者,我深刻體會到API接口已成為現代軟件開發的核心基石。在這個萬物互聯的時代,掌握API調用技術不再是錦上添花,而是開發者必備的基本技能。本文將帶領大家深入Python API接口的奇妙世界,從基礎概念到實戰應用,全方位剖析如何利用Python高效調用各類API接口。我們將探討RESTful API、GraphQL、WebSocket等不同類型接口的特點與應用場景,通過實際案例演示如何使用requests、aiohttp等庫進行接口調用,并深入討論認證機制、錯誤處理、性能優化等關鍵技術點。無論你是剛入門的新手,還是尋求提升的老手,這篇文章都將為你提供系統化的API接口調用知識體系,助你在這個API驅動的世界中游刃有余。讓我們一起揭開API的神秘面紗,探索如何通過簡單的Python代碼連接無限可能!
一、API基礎知識
1.1 什么是API
API(Application Programming Interface,應用程序編程接口)是軟件組件之間定義的交互方式,允許不同的應用程序相互通信和共享數據。
# API調用的基本模式
import requests# 發送請求到API端點
response = requests.get('https://api.example.com/data')# 處理響應
if response.status_code == 200:data = response.json() # 解析JSON響應print(data)
else:print(f"請求失敗: {response.status_code}")
1.2 API的類型
圖1:API類型分類流程圖 - 展示了主要API類型及其特點
1.3 API認證方式
不同的API使用不同的認證機制來確保安全訪問:
# API密鑰認證
import requestsapi_key = "your_api_key_here"
headers = {"Authorization": f"Bearer {api_key}"}
response = requests.get("https://api.example.com/data", headers=headers)# OAuth 2.0認證
from requests_oauthlib import OAuth2Sessionclient_id = "your_client_id"
client_secret = "your_client_secret"
oauth = OAuth2Session(client_id)
# 獲取授權URL和狀態
authorization_url, state = oauth.authorization_url("https://example.com/oauth/authorize")
# 用戶授權后獲取token
token = oauth.fetch_token("https://example.com/oauth/token",authorization_response="callback_url_with_code",client_secret=client_secret)
# 使用token訪問API
response = oauth.get("https://api.example.com/data")
二、Python API調用基礎
2.1 常用HTTP庫對比
庫名稱 | 特點 | 適用場景 | 異步支持 | 易用性 |
---|---|---|---|---|
requests | 簡單直觀,功能豐富 | 一般API調用 | 否 | ★★★★★ |
aiohttp | 異步IO,高性能 | 高并發場景 | 是 | ★★★★☆ |
httpx | 現代化,支持異步 | 需要HTTP/2的場景 | 是 | ★★★★☆ |
urllib3 | 底層控制,線程安全 | 需要細粒度控制 | 否 | ★★★☆☆ |
pycurl | 高性能,多協議支持 | 性能關鍵場景 | 否 | ★★☆☆☆ |
2.2 使用requests庫調用RESTful API
import requests
import json# GET請求
def get_data(url, params=None, headers=None):"""發送GET請求獲取數據參數:url (str): API端點URLparams (dict): 查詢參數headers (dict): 請求頭返回:dict: 響應數據"""response = requests.get(url, params=params, headers=headers)response.raise_for_status() # 如果請求失敗則拋出異常return response.json()# POST請求
def create_resource(url, data, headers=None):"""發送POST請求創建資源參數:url (str): API端點URLdata (dict): 要發送的數據headers (dict): 請求頭返回:dict: 響應數據"""if headers is None:headers = {"Content-Type": "application/json"}response = requests.post(url, data=json.dumps(data), headers=headers)response.raise_for_status()return response.json()# 使用示例
try:# 獲取用戶列表users = get_data("https://api.example.com/users", params={"page": 1, "limit": 10},headers={"Authorization": "Bearer token123"})print(f"獲取到 {len(users)} 個用戶")# 創建新用戶new_user = create_resource("https://api.example.com/users",{"name": "張三", "email": "zhangsan@example.com"},{"Authorization": "Bearer token123"})print(f"創建用戶成功: {new_user['id']}")except requests.exceptions.HTTPError as e:print(f"HTTP錯誤: {e}")
except requests.exceptions.ConnectionError:print("連接錯誤: 請檢查網絡連接")
except requests.exceptions.Timeout:print("超時錯誤: 請求超時")
except requests.exceptions.RequestException as e:print(f"請求錯誤: {e}")
2.3 異步API調用
import asyncio
import aiohttp
import timeasync def fetch_data(session, url):"""異步獲取單個URL的數據"""async with session.get(url) as response:return await response.json()async def fetch_all(urls):"""并發獲取多個URL的數據"""async with aiohttp.ClientSession() as session:tasks = [fetch_data(session, url) for url in urls]# 并發執行所有任務results = await asyncio.gather(*tasks)return results# 使用示例
async def main():# 需要獲取數據的API端點列表urls = ["https://api.example.com/users/1","https://api.example.com/users/2","https://api.example.com/users/3","https://api.example.com/users/4","https://api.example.com/users/5"]start_time = time.time()results = await fetch_all(urls)end_time = time.time()print(f"異步獲取 {len(results)} 個API結果,耗時: {end_time - start_time:.2f}秒")return results# 運行異步主函數
if __name__ == "__main__":results = asyncio.run(main())## 三、實戰案例:常用API接口調用### 3.1 天氣API調用```python
import requests
from datetime import datetimedef get_weather(city, api_key):"""獲取指定城市的天氣信息參數:city (str): 城市名稱api_key (str): OpenWeatherMap API密鑰返回:dict: 天氣信息"""base_url = "https://api.openweathermap.org/data/2.5/weather"params = {"q": city,"appid": api_key,"units": "metric", # 使用攝氏度"lang": "zh_cn" # 中文結果}response = requests.get(base_url, params=params)response.raise_for_status()weather_data = response.json()# 格式化天氣信息formatted_data = {"城市": weather_data["name"],"天氣": weather_data["weather"][0]["description"],"溫度": f"{weather_data['main']['temp']}°C","體感溫度": f"{weather_data['main']['feels_like']}°C","濕度": f"{weather_data['main']['humidity']}%","風速": f"{weather_data['wind']['speed']}m/s","更新時間": datetime.fromtimestamp(weather_data["dt"]).strftime("%Y-%m-%d %H:%M:%S")}return formatted_data# 使用示例
if __name__ == "__main__":API_KEY = "your_openweathermap_api_key" # 替換為你的API密鑰city = "北京"try:weather_info = get_weather(city, API_KEY)print(f"== {weather_info['城市']}天氣信息 ==")for key, value in weather_info.items():if key != "城市":print(f"{key}: {value}")except requests.exceptions.HTTPError as e:print(f"獲取天氣信息失敗: {e}")
3.2 翻譯API調用
import requests
import uuid
import hashlib
import timedef translate_text(text, from_lang, to_lang, app_id, app_key):"""使用百度翻譯API翻譯文本參數:text (str): 要翻譯的文本from_lang (str): 源語言代碼,如'auto'自動檢測,'zh'中文,'en'英文to_lang (str): 目標語言代碼app_id (str): 百度翻譯API的APP IDapp_key (str): 百度翻譯API的密鑰返回:str: 翻譯后的文本"""endpoint = "https://fanyi-api.baidu.com/api/trans/vip/translate"# 生成隨機數salt = str(uuid.uuid4())# 計算簽名: appid+q+salt+密鑰sign_str = app_id + text + salt + app_keysign = hashlib.md5(sign_str.encode()).hexdigest()# 組裝請求參數params = {'q': text,'from': from_lang,'to': to_lang,'appid': app_id,'salt': salt,'sign': sign}# 發送請求response = requests.get(endpoint, params=params)result = response.json()# 檢查是否有錯誤if 'error_code' in result:raise Exception(f"翻譯錯誤 (代碼: {result['error_code']}): {result.get('error_msg', '未知錯誤')}")# 提取翻譯結果translated_text = result['trans_result'][0]['dst']return translated_text# 使用示例
if __name__ == "__main__":APP_ID = "your_baidu_app_id" # 替換為你的百度翻譯APP IDAPP_KEY = "your_baidu_app_key" # 替換為你的百度翻譯密鑰text_to_translate = "人工智能正在改變我們的世界"try:# 中文翻譯為英文translated = translate_text(text_to_translate, 'zh', 'en', APP_ID, APP_KEY)print(f"原文: {text_to_translate}")print(f"譯文: {translated}")# 防止API調用過于頻繁time.sleep(1)# 再將結果翻譯回中文back_translated = translate_text(translated, 'en', 'zh', APP_ID, APP_KEY)print(f"回譯: {back_translated}")except Exception as e:print(f"翻譯失敗: {e}")
圖3:翻譯API調用時序圖 - 展示了翻譯API的完整調用流程
3.3 圖像識別API調用
import requests
import base64
import jsondef recognize_image(image_path, api_key):"""使用百度AI圖像識別API識別圖片內容參數:image_path (str): 圖片文件路徑api_key (str): 百度AI平臺的API密鑰返回:dict: 識別結果"""# 獲取訪問令牌def get_access_token(api_key, secret_key):url = "https://aip.baidubce.com/oauth/2.0/token"params = {"grant_type": "client_credentials","client_id": api_key,"client_secret": secret_key}response = requests.post(url, params=params)return response.json().get("access_token")# 讀取圖片文件并進行base64編碼with open(image_path, "rb") as f:image_data = base64.b64encode(f.read()).decode("utf-8")# 獲取訪問令牌access_token = get_access_token(api_key["api_key"], api_key["secret_key"])# 調用通用物體識別APIrecognize_url = f"https://aip.baidubce.com/rest/2.0/image-classify/v2/advanced_general?access_token={access_token}"headers = {"Content-Type": "application/x-www-form-urlencoded"}data = {"image": image_data}response = requests.post(recognize_url, headers=headers, data=data)result = response.json()if "error_code" in result:raise Exception(f"識別錯誤 (代碼: {result['error_code']}): {result.get('error_msg', '未知錯誤')}")return result# 使用示例
if __name__ == "__main__":# 百度AI平臺的API密鑰信息API_INFO = {"api_key": "your_baidu_api_key","secret_key": "your_baidu_secret_key"}# 要識別的圖片路徑IMAGE_PATH = "example.jpg"try:result = recognize_image(IMAGE_PATH, API_INFO)print("圖像識別結果:")for item in result["result"]:print(f"- {item['keyword']}: 置信度 {item['score']*100:.2f}%")except Exception as e:print(f"識別失敗: {e}")## 四、API接口性能優化### 4.1 API調用性能指標```mermaid
%%{init: {'theme': 'neutral', 'themeVariables': { 'primaryColor': '#6495ED', 'primaryTextColor': '#fff', 'primaryBorderColor': '#4169E1', 'lineColor': '#6495ED', 'secondaryColor': '#B0C4DE', 'tertiaryColor': '#E6E6FA' }}}%%
pietitle API調用性能影響因素占比"網絡延遲" : 35"服務器處理時間" : 25"數據序列化/反序列化" : 15"認證開銷" : 10"客戶端處理" : 10"其他因素" : 5
圖2:API調用性能影響因素占比餅圖 - 展示了影響API調用性能的主要因素及其占比
4.2 連接池與會話復用
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retrydef create_session():"""創建一個具有連接池和重試機制的會話對象返回:requests.Session: 配置好的會話對象"""session = requests.Session()# 配置重試策略retry_strategy = Retry(total=3, # 最多重試3次backoff_factor=0.5, # 重試間隔 = {backoff factor} * (2 ^ ({number of previous retries}))status_forcelist=[429, 500, 502, 503, 504], # 這些狀態碼會觸發重試allowed_methods=["GET", "POST"] # 允許重試的HTTP方法)# 配置適配器,最大連接數為10adapter = HTTPAdapter(max_retries=retry_strategy, pool_connections=10, pool_maxsize=10)# 將適配器掛載到會話session.mount("http://", adapter)session.mount("https://", adapter)return session# 使用示例
def fetch_multiple_apis(urls):"""使用會話復用方式獲取多個API數據參數:urls (list): API端點URL列表返回:list: 響應數據列表"""session = create_session()results = []for url in urls:try:response = session.get(url, timeout=(3.05, 27)) # (連接超時, 讀取超時)response.raise_for_status()results.append(response.json())except requests.exceptions.RequestException as e:print(f"請求 {url} 失敗: {e}")results.append(None)return results# 使用示例
if __name__ == "__main__":api_urls = ["https://api.example.com/data/1","https://api.example.com/data/2","https://api.example.com/data/3"]results = fetch_multiple_apis(api_urls)print(f"成功獲取 {sum(1 for r in results if r is not None)} 個API結果,共 {len(api_urls)} 個")
圖4:不同HTTP庫性能比較圖 - 展示了不同HTTP庫在不同請求數量下的性能表現
4.3 異步并發與限流
import asyncio
import aiohttp
import time
from aiohttp import ClientSession
from asyncio import Semaphoreclass RateLimiter:"""API調用限流器"""def __init__(self, calls_limit, time_period):"""初始化限流器參數:calls_limit (int): 時間段內允許的最大調用次數time_period (float): 時間段長度(秒)"""self.calls_limit = calls_limitself.time_period = time_periodself.calls_times = []async def acquire(self):"""獲取調用許可,必要時等待"""now = time.time()# 清理過期的調用記錄self.calls_times = [t for t in self.calls_times if now - t <= self.time_period]# 如果已達到限制,等待到最早的調用過期if len(self.calls_times) >= self.calls_limit:oldest_call = self.calls_times[0]wait_time = self.time_period - (now - oldest_call)if wait_time > 0:await asyncio.sleep(wait_time)# 記錄本次調用時間self.calls_times.append(time.time())async def fetch_with_rate_limit(session, url, rate_limiter, semaphore):"""使用限流和并發控制獲取API數據參數:session (ClientSession): aiohttp會話url (str): API端點URLrate_limiter (RateLimiter): 限流器semaphore (Semaphore): 并發控制信號量返回:dict: API響應數據"""# 獲取限流許可await rate_limiter.acquire()# 獲取并發許可async with semaphore:try:async with session.get(url) as response:if response.status == 200:return await response.json()else:print(f"請求失敗: {url}, 狀態碼: {response.status}")return Noneexcept Exception as e:print(f"請求異常: {url}, 錯誤: {e}")return Noneasync def fetch_all_apis(urls, rate_limit=10, period=1.0, max_concurrency=5):"""批量獲取API數據,帶限流和并發控制參數:urls (list): API端點URL列表rate_limit (int): 每個時間段內的最大請求數period (float): 時間段長度(秒)max_concurrency (int): 最大并發請求數返回:list: API響應數據列表"""# 創建限流器和信號量rate_limiter = RateLimiter(rate_limit, period)semaphore = Semaphore(max_concurrency)async with ClientSession() as session:tasks = [fetch_with_rate_limit(session, url, rate_limiter, semaphore)for url in urls]return await asyncio.gather(*tasks)
圖5:API調用策略選擇矩陣 - 展示了不同API調用優化策略的實現復雜度與性能提升對比
五、API接口調用架構設計
5.1 API客戶端封裝
class APIClient:"""通用API客戶端封裝"""def __init__(self, base_url, auth_token=None, timeout=30):"""初始化API客戶端參數:base_url (str): API基礎URLauth_token (str): 認證令牌timeout (int): 請求超時時間(秒)"""self.base_url = base_url.rstrip('/')self.timeout = timeoutself.session = requests.Session()# 設置通用請求頭self.session.headers.update({"Content-Type": "application/json","Accept": "application/json"})# 設置認證令牌if auth_token:self.session.headers.update({"Authorization": f"Bearer {auth_token}"})def _build_url(self, endpoint):"""構建完整的API URL"""endpoint = endpoint.lstrip('/')return f"{self.base_url}/{endpoint}"def _handle_response(self, response):"""處理API響應"""try:response.raise_for_status()return response.json()except requests.exceptions.HTTPError as e:# 嘗試解析錯誤響應error_detail = {}try:error_detail = response.json()except:error_detail = {"message": response.text}raise APIError(status_code=response.status_code,message=f"HTTP錯誤: {e}",detail=error_detail)except ValueError:# 響應不是有效的JSONreturn {"raw_content": response.text}def get(self, endpoint, params=None):"""發送GET請求"""url = self._build_url(endpoint)response = self.session.get(url, params=params, timeout=self.timeout)return self._handle_response(response)def post(self, endpoint, data=None, json_data=None):"""發送POST請求"""url = self._build_url(endpoint)response = self.session.post(url, data=data, json=json_data, timeout=self.timeout)return self._handle_response(response)def put(self, endpoint, data=None, json_data=None):"""發送PUT請求"""url = self._build_url(endpoint)response = self.session.put(url, data=data, json=json_data, timeout=self.timeout)return self._handle_response(response)def delete(self, endpoint, params=None):"""發送DELETE請求"""url = self._build_url(endpoint)response = self.session.delete(url, params=params, timeout=self.timeout)return self._handle_response(response)class APIError(Exception):"""API錯誤異常"""def __init__(self, status_code, message, detail=None):self.status_code = status_codeself.message = messageself.detail = detailsuper().__init__(self.message)def __str__(self):if self.detail:return f"{self.message} - {self.detail}"return self.message# 使用示例
if __name__ == "__main__":# 創建API客戶端client = APIClient(base_url="https://api.example.com/v1",auth_token="your_auth_token_here")try:# 獲取用戶列表users = client.get("/users", params={"limit": 10})print(f"獲取到 {len(users)} 個用戶")# 創建新用戶new_user = client.post("/users", json_data={"name": "張三","email": "zhangsan@example.com"})print(f"創建用戶成功: ID={new_user['id']}")except APIError as e:print(f"API錯誤: {e}")
5.2 API接口適配器模式
圖6:API接口適配器架構圖 - 展示了使用適配器模式統一不同API接口的架構設計
from abc import ABC, abstractmethod
抽象接口
class TranslationService(ABC):
“”“翻譯服務抽象接口”“”
@abstractmethod
def translate(self, text, source_lang, target_lang):"""翻譯文本參數:text (str): 要翻譯的文本source_lang (str): 源語言代碼target_lang (str): 目標語言代碼返回:str: 翻譯后的文本"""pass
具體實現 - 百度翻譯
class BaiduTranslation(TranslationService):
“”“百度翻譯服務實現”“”
def __init__(self, app_id, app_key):self.app_id = app_idself.app_key = app_keydef translate(self, text, source_lang, target_lang):# 轉換語言代碼格式source = self._convert_lang_code(source_lang)target = self._convert_lang_code(target_lang)# 調用百度翻譯APIimport uuidimport hashlibimport requestsendpoint = "https://fanyi-api.baidu.com/api/trans/vip/translate"salt = str(uuid.uuid4())sign_str = self.app_id + text + salt + self.app_keysign = hashlib.md5(sign_str.encode()).hexdigest()params = {'q': text,'from': source,'to': target,'appid': self.app_id,'salt': salt,'sign': sign}response = requests.get(endpoint, params=params)result = response.json()if 'error_code' in result:raise Exception(f"翻譯錯誤: {result.get('error_msg', '未知錯誤')}")return result['trans_result'][0]['dst']def _convert_lang_code(self, lang_code):"""將標準語言代碼轉換為百度API使用的代碼"""# 語言代碼映射表mapping = {"en": "en","zh": "zh","ja": "jp","ko": "kor","fr": "fra","es": "spa","auto": "auto"}return mapping.get(lang_code.lower(), lang_code)
具體實現 - Google翻譯
class GoogleTranslation(TranslationService):
“”“Google翻譯服務實現”“”
def __init__(self, api_key):self.api_key = api_keydef translate(self, text, source_lang, target_lang):# 這里是Google翻譯API的實現# 實際代碼中需要使用Google Cloud Translation APIimport requestsurl = "https://translation.googleapis.com/language/translate/v2"params = {"q": text,"source": source_lang,"target": target_lang,"key": self.api_key}response = requests.post(url, params=params)result = response.json()if "error" in result:raise Exception(f"翻譯錯誤: {result['error']['message']}")return result["data"]["translations"][0]["translatedText"]
使用示例
def translate_with_service(service, text, source=“auto”, target=“en”):
“”"
使用指定的翻譯服務翻譯文本
參數:service (TranslationService): 翻譯服務實例text (str): 要翻譯的文本source (str): 源語言代碼target (str): 目標語言代碼返回:str: 翻譯后的文本
"""
try:result = service.translate(text, source, target)return result
except Exception as e:print(f"翻譯失敗: {e}")return None
客戶端代碼
if name == “main”:
# 創建百度翻譯服務
baidu_service = BaiduTranslation(
app_id=“your_baidu_app_id”,
app_key=“your_baidu_app_key”
)
# 創建Google翻譯服務
google_service = GoogleTranslation(api_key="your_google_api_key"
)# 要翻譯的文本
text = "人工智能正在改變世界"# 使用百度翻譯
baidu_result = translate_with_service(baidu_service, text, "zh", "en")
print(f"百度翻譯結果: {baidu_result}")# 使用Google翻譯
google_result = translate_with_service(google_service, text, "zh", "en")
print(f"Google翻譯結果: {google_result}")
六、總結與最佳實踐
“API不僅僅是技術接口,更是連接不同系統、不同團隊、不同思想的橋梁。優秀的API調用代碼應當像優秀的外交官一樣,既能準確傳達信息,又能優雅處理各種意外情況。” —— 軟件架構師諺語
在這個萬物互聯的時代,API已經成為現代軟件開發的核心基礎設施。通過本文的學習,我們已經掌握了使用Python調用各種API接口的基本技能和高級技巧。以下是一些關鍵的最佳實踐總結:
-
選擇合適的HTTP庫:根據項目需求選擇合適的HTTP庫,一般情況下requests是最佳選擇,但高并發場景應考慮aiohttp等異步庫。
-
錯誤處理與重試:永遠不要假設API調用會成功,始終實現完善的錯誤處理和適當的重試機制。
-
性能優化:對于頻繁調用的API,應使用連接池、會話復用等技術減少連接開銷。
-
限流控制:尊重API提供方的限制,實現客戶端限流以避免被封禁。
-
抽象與適配:使用適配器模式等設計模式,將具體API實現與業務邏輯分離。
-
安全性考慮:妥善保管API密鑰,避免硬編碼在代碼中,使用環境變量或配置文件存儲敏感信息。
-
文檔與測試:為API調用代碼編寫清晰的文檔和單元測試,確保其可維護性和穩定性。
圖7:API調用最佳實踐思維導圖 - 展示了API調用開發中的關鍵最佳實踐
結語
從最初的簡單HTTP請求,到如今的復雜分布式系統集成,API技術一直在不斷演進。在這個過程中,Python憑借其簡潔的語法和豐富的生態系統,成為了API調用的理想語言之一。
通過本文的學習,我們已經掌握了從基礎到高級的Python API調用技術,包括RESTful API調用、異步并發、性能優化、架構設計等方面的知識。這些技能將幫助你在實際項目中更加高效地集成各種第三方服務,構建更加強大的應用程序。
記住,API調用不僅僅是技術問題,更是一種溝通藝術。優秀的API調用代碼應當既能準確傳達需求,又能優雅處理各種異常情況。希望本文能夠幫助你在API的海洋中航行得更加順利,構建出更加強大、可靠的應用程序。
在未來的開發中,隨著微服務架構、云原生應用的普及,API調用技術將變得越來越重要。持續學習、實踐和優化你的API調用代碼,將使你在技術浪潮中保持競爭力。讓我們一起,在這個API驅動的世界中,用代碼連接無限可能!
■ 我是蔣星熠Jaxonic!如果這篇文章在你的技術成長路上留下了印記
■ 👁 【關注】與我一起探索技術的無限可能,見證每一次突破
■ 👍 【點贊】為優質技術內容點亮明燈,傳遞知識的力量
■ 🔖 【收藏】將精華內容珍藏,隨時回顧技術要點
■ 💬 【評論】分享你的獨特見解,讓思維碰撞出智慧火花
■ 🗳 【投票】用你的選擇為技術社區貢獻一份力量
■ 技術路漫漫,讓我們攜手前行,在代碼的世界里摘取屬于程序員的那片星辰大海!
參考鏈接
- Python Requests官方文檔
- aiohttp異步HTTP客戶端/服務器文檔
- RESTful API設計最佳實踐
- 百度翻譯API開發者文檔
- OpenWeatherMap API文檔