Photo by Nirmal Rajendharkumar on Unsplash
在現今很多網站,都會透過API(Application Programming Interface)的方式來提供服務,讓用呼端能夠藉由這個介面存取其資料,進行多樣化的應用開發。本文就以KKBOX Open API為例,實作一個簡單的專案,示範Python如何存取音樂排行榜API,並且可以讓使用者選擇想聽的排行榜類別,試聽其中的歌曲。
經過本文的教學,將會瞭解API的基本觀念,以及學會如何解析Python存取API後的回傳結果,並且篩選所需的欄位,重點包含了:
經過本文的教學,將會瞭解API的基本觀念,以及學會如何解析Python存取API後的回傳結果,並且篩選所需的欄位,重點包含了:
- 什麼是API
- 專案前置準備
- KKBOX Open API
- 用戶端憑證(Client Credentials)
- KKBOX Open API - Charts
一、什麼是API
各位可以將API(Application Programming Interface)想像是一個大門,要進入存取必須提供合法的帳號及密碼,才能拿到存取憑證(Access Token),之後要存取門後的API資源,只要帶著這個憑證,就可以進行存取。
而實際上API就是一組網址,透過HTTP協定來和用戶端進行溝通。舉例來說,各位可以開啟Chrome瀏覽器,按下F12進入開發者視窗,點擊Network頁籤,接著輸入google.com.tw網址,可以看到類似下圖的結果:
而實際上API就是一組網址,透過HTTP協定來和用戶端進行溝通。舉例來說,各位可以開啟Chrome瀏覽器,按下F12進入開發者視窗,點擊Network頁籤,接著輸入google.com.tw網址,可以看到類似下圖的結果:
點選任一個網址,可以看到以下的資訊:
其中的Headers(標頭)就是瀏覽器發送至Google的資訊,如果換成是存取KKBOX Open API,Request URL就是API網址,Request Method有幾個常用的類型,分別有:
- GET(查詢資料)
- POST(新增資料)
- PUT(修改資料)
- DELETE(刪除資料)
以上四個是在存取API時,常用的HTTP動詞。而Response頁籤中的內容即是Google回傳給瀏覽器的結果。
二、專案前置準備
有了基本的API觀念後,接著建立一個專案,並且開啟Python開發工具,本文將以Visual Studio Code來進行教學。透過 pipenv 套件管理工具來為專案建立虛擬環境及安裝requests套件(Package),如下範例:
接下來,利用pipenv shell指令進入虛擬環境後,在專案中新增charts.py檔,完成即可進行今天KKBOX Open API的Python實作練習囉。
三、KKBOX Open API
KKBOX Open API為KKBOX平台所提供的開放API,透過此API即可取得歌曲、排行榜、熱門歌單等音樂資訊,並且有提供幾個程式語言的軟體開發套件(SDK, Software Development Kit),提升開發專案的效率,而本文為讓各位瞭解背後執行的原理,所以利用原始的存取方式來進行教學。
在進行開發前,前往KKBOX Open API文件首頁,如下圖:
點擊上方的My Apps來建立一個App,如下圖:
接著註冊KKBOX帳號,並且登入後,就可以進行建立App的動作了,如下圖:
在進行開發前,前往KKBOX Open API文件首頁,如下圖:
點擊上方的My Apps來建立一個App,如下圖:
接著註冊KKBOX帳號,並且登入後,就可以進行建立App的動作了,如下圖:
第一次建立App會看到此畫面,接著點擊Create new app,輸入App名稱及簡單描述,如下範例:
送出資料後,就會得到一組屬於這個App的ID(帳號)及Secret(密碼),如下範例:
這組ID(帳號)及Secret(密碼)將會是接下來存取KKBOX Open API時,用來取得憑證的依據。
四、用戶端憑證(Client Credentials)
App建立完成後,點擊上方API Reference(API參考文件),左側可以看到所有的KKBOX Open API,如下範例:
要存取API前,必須提供剛剛建立App時所拿到的ID(帳號)及Secret(密碼),才能取得KKBOX用戶端憑證(Client Credentials 或 Access Token),並且在所有的API呼叫中,都要帶著,讓KKBOX知道您是通過驗證的用戶端或專案,才會允許您的呼叫動作。
那要如何取得憑證呢?在API Reference的Client Credentials Flow中,說明了取得憑證的API網址、標頭(Header)及參數資訊,如下:
那要如何取得憑證呢?在API Reference的Client Credentials Flow中,說明了取得憑證的API網址、標頭(Header)及參數資訊,如下:
開啟 charts.py ,建立一個名稱為 get_access_token()的函式(Function) ,如下範例:
import requests
# 取得Token
def get_access_token():
#API網址
url = "https://account.kkbox.com/oauth2/token"
#標頭
headers = {
"Content-Type": "application/x-www-form-urlencoded",
"Host": "account.kkbox.com"
}
#參數
data = {
"grant_type": "client_credentials",
"client_id": "貼上ID內容",
"client_secret": "貼上Secret內容"
}
access_token = requests.post(url, headers=headers, data=data)
return access_token.json()["access_token"]
由於需要發出request請求,所以引用requests套件(Package),並且根據API Reference(API參考文件),分別指派API網址、標頭(Header)及參數(data)資訊,接著透過requests套件(Package)的post方法取得結果,最後利用json()方法將結果轉換為字典(Dictionary),再使用 [] 符號讀取憑證欄位資料。
五、KKBOX Open API - Charts
有了存取憑證(Access Token)後,就可以進行KKBOX Open API的呼叫了,接下來將以Charts API為例,取得KKBOX音樂排行榜的資料。
首先,要取得各種音樂排行榜的清單,可以透過 /charts API網址來取得,而API Reference(API參考文件)說明如下:
首先,要取得各種音樂排行榜的清單,可以透過 /charts API網址來取得,而API Reference(API參考文件)說明如下:
在charts.py中,新增一個名稱為 get_charts()的函式(Function) ,如下範例:
# 取得各種音樂排行榜列表
def get_charts():
#取得存取憑證
access_token = get_access_token()
#取得音樂排行榜列表API網址
url = "https://api.kkbox.com/v1.1/charts"
#標頭
headers = {
"accept": "application/json",
"authorization": "Bearer " + access_token #帶著存取憑證
}
#參數
params = {
"territory": "TW" #台灣領域
}
response = requests.get(url, headers=headers, params=params)
result = response.json()["data"]
for item in result:
print(item["id"], item["title"])
get_charts()
回傳結果範例
{
"data": [
{
"id": "LZPhK2EyYzN15dU-PT",
"title": "綜合新歌即時榜",
"description": "綜合新歌即時榜",
"url": "https://www.kkbox.com/tw/tc/playlist/LZPhK2EyYzN15dU-PT",
"images": [
{
"height": 300,
"width": 300,
"url": "https://i.kfs.io/playlist/global/59599602v1259/cropresize/300x300.jpg"
},
{
"height": 600,
"width": 600,
"url": "https://i.kfs.io/playlist/global/59599602v1259/cropresize/600x600.jpg"
},
{
"height": 1000,
"width": 1000,
"url": "https://i.kfs.io/playlist/global/59599602v1259/cropresize/1000x1000.jpg"
}
],
"updated_at": "2019-08-02T03:01:58+00:00",
"owner": {
"id": "T-YMdq3gnf6AVbuqgt",
"url": "https://www.kkbox.com/tw/profile/T-YMdq3gnf6AVbuqgt",
"name": "KKBOX",
"description": "",
"images": [
{
"height": 75,
"width": 75,
"url": "https://i.kfs.io/muser/global/noimg/cropresize/75x75.jpg"
},
{
"height": 180,
"width": 180,
"url": "https://i.kfs.io/muser/global/noimg/cropresize/180x180.jpg"
},
{
"height": 300,
"width": 300,
"url": "https://i.kfs.io/muser/global/noimg/cropresize/300x300.jpg"
}
]
}
},
...
],
"paging": {
"offset": 0,
"limit": 5,
"previous": null,
"next": null
},
"summary": {
"total": 29
}
}
前面有提到,要呼叫任何的KKBOX Open API時,標頭(Header)都要帶有存取憑證(Access Token),所以在第12行的標頭(headers) authorization 欄位,要加上存取憑證(Access Token)。而 territory 參數需指定API參考文件中的代碼。
由於要執行查詢的動作,所以透過requests套件(Package)的get()方法來進行API呼叫。從API文件提供的回傳結果範例可以看到,利用json()方法轉為字典(Dictionary)後,可以透過 [] 符號存取data欄位資料,也就是串列(List),接著就可以利用for迴圈進行讀取,最後取得id(列表ID)及title(列表名稱),執行結果如下:
由於要執行查詢的動作,所以透過requests套件(Package)的get()方法來進行API呼叫。從API文件提供的回傳結果範例可以看到,利用json()方法轉為字典(Dictionary)後,可以透過 [] 符號存取data欄位資料,也就是串列(List),接著就可以利用for迴圈進行讀取,最後取得id(列表ID)及title(列表名稱),執行結果如下:
要取得各個排行榜中的歌曲,就要呼叫另一個 /charts/:chart_id/tracks API網址,並且傳入此列表ID,API文件說明如下:
在charts.py中,新增一個名稱為get_charts_tracks(chart_id)的函式(Function),如下範例:
# 取得該音樂排行榜的歌曲列表
def get_charts_tracks(chart_id):
#存取憑證
access_token = get_access_token()
#取得音樂排行榜列表中的歌曲API網址
url = "https://api.kkbox.com/v1.1/charts/" + chart_id + "/tracks"
#標頭
headers = {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
#參數
params = {
"territory": "TW" #台灣領域
}
response = requests.get(url, headers=headers, params=params)
result = response.json()["data"]
for item in result:
print([item["name"], item["url"]])
get_charts()
print("===========================================")
try:
chart_id = input("請貼上想聽的音樂排行榜ID: ")
get_charts_tracks(chart_id)
except KeyError:
print("請貼上正確的音樂排行榜ID")
回傳結果範例
{
"data": [
{
"id": "Cl6IBBqIFKtg2hkWuB",
"name": "有一種悲傷 (A Kind of Sorrow)",
"duration": 237008,
"url": "https://www.kkbox.com/tw/tc/song/EJT009KS-TZFBgeRFBgeR0XL-index.html",
"track_number": 1,
"explicitness": false,
"available_territories": [
"TW",
"HK",
"SG",
"MY",
"JP"
],
"album": {
"id": "OtS1j6YhEqbM8XuF5D",
"name": "有一種悲傷 (A Kind of Sorrow)",
"url": "https://www.kkbox.com/tw/tc/album/aMZ0PysNRqgHN0F2RKf6009H-index.html",
"explicitness": false,
"available_territories": [
"TW",
"HK",
"SG",
"MY",
"JP"
],
"release_date": "2018-10-12",
"images": [
{
"height": 160,
"width": 160,
"url": "https://i.kfs.io/album/global/40716998,1v1/fit/160x160.jpg"
},
{
"height": 500,
"width": 500,
"url": "https://i.kfs.io/album/global/40716998,1v1/fit/500x500.jpg"
},
{
"height": 1000,
"width": 1000,
"url": "https://i.kfs.io/album/global/40716998,1v1/fit/1000x1000.jpg"
}
],
"artist": {
"id": "Osbh3TUzyafhBl0WD5",
"name": "A-Lin",
"url": "https://www.kkbox.com/tw/tc/artist/RTQrEhYKUkU5NCX0F03LZ08J-index-1.html",
"images": [
{
"height": 160,
"width": 160,
"url": "https://i.kfs.io/artist/global/13667,0v22/fit/160x160.jpg"
},
{
"height": 300,
"width": 300,
"url": "https://i.kfs.io/artist/global/13667,0v22/fit/300x300.jpg"
}
]
}
}
},
...
],
"paging": {
"offset": 0,
"limit": 2,
"previous": null,
"next": "https://api.kkbox.com/v1.1/charts/X-6lSz-IwzDxkPuDP-/tracks?limit=2&territory=TW&offset=2"
},
"summary": {
"total": 100
}
}
除了需在標頭(headers)的authorization加上存取憑證(Access Token)外,在第8行的API網址需加上列表ID,而參數的部分這邊僅傳入台灣領域。
此API同樣為查詢動作,所以透過requests套件(Package)的get()方法進行呼叫,將回傳結果利用json()方法轉為字典(Dictionary)後,使用 [] 符號存取data欄位中的資料,最後利用for迴圈讀取name(歌曲名稱)及url(歌曲試聽網址),為了輸出結果的可讀性,所以將此兩個欄位資料轉型為串列(List)。
由於和使用者有互動的效果,所以利用input()函式取得使用者貼上的列表ID,為了防止隨意輸入產生錯誤,使用Python例外處理機制,顯示警告訊息,如果無誤則將列表ID傳入get_charts_tracks(chart_id)函式,來取得列表中的歌曲,執行結果如下:
由於和使用者有互動的效果,所以利用input()函式取得使用者貼上的列表ID,為了防止隨意輸入產生錯誤,使用Python例外處理機制,顯示警告訊息,如果無誤則將列表ID傳入get_charts_tracks(chart_id)函式,來取得列表中的歌曲,執行結果如下:
接下來,就可以按著Ctrl鍵不放,點擊後面的連結,開啟網頁版KKBOX來進行試聽囉~
六、小結
以上就是利用Python存取KKBOX Open API的簡單應用,各位藉此瞭解Python呼叫API的方式及回傳結果的解析後,可以試著練習其他的API,如果在練習的過程中有碰到任何問題,歡迎留言分享。
如果您喜歡我的文章,請幫我按五下Like(使用Google或Facebook帳號免費註冊),支持我創作教學文章,回饋由LikeCoin基金會出資,完全不會花到錢,感謝大家。
沒有看到 My App
回覆刪除已在文章中補充說明,如果還有遇到問題,歡迎留言討論
刪除