Home >> Blog >> Python API 教學:API 入門 一起學習Python
Python API 教學:API 入門 一起學習Python
在本 Python API 教材中,我們將學習如何為數據科學項目檢索數據。在線有數百萬個 API 提供對數據的訪問。Reddit、Twitter和Facebook等網站都通過其 API 提供某些數據。
要使用 API,您需要向遠程 Web 伺服器發出請求,然後檢索您需要的數據。
但是為什
- 數據變化很快。這方面的一個例子是股票價格數據。重新生成數據集並每分鐘下載一次並沒有什麼意義——這會佔用大量帶寬,而且速度非常慢。
- 您需要大得多的數據集的一小部分。Reddit 評論就是一個例子。如果您只想在 Reddit 上發表自己的評論怎麼辦?下載整個 Reddit 數據庫,然後只過濾你自己的評論沒有多大意義。
- 涉及重複計算。Spotify 有一個 API,可以告訴你一段音樂的流派。從理論上講,您可以創建自己的分類器,並使用它來計算音樂類別,但您永遠不會擁有像 Spotify 那樣多的數據。
在上述情況下,API 是正確的解決方案。在這篇博文中,我們將查詢一個簡單的 API 來檢索有關國際空間站(ISS) 的數據。
關於本 Python API 教材
本教材基於我們關於 Python 中的 API 和 Webscraping 的交互式課程的一部分,您可以免費開始。
對於本教材,我們假設您了解在 Python 中處理數據的一些基礎知識。如果您不這樣做,您可能想嘗試我們的免費 Python 基礎課程。
如果您正在尋找更高級的東西,請查看我們的中級 API 教材。
什麼是 API?
API 或應用程序編寫程式接口是一個伺服器,您可以使用它來檢索數據並將數據發送到使用代碼。API 最常用於檢索數據,這將是本初學者教材的重點。
當我們想從 API 接收數據時,我們需要發出請求。請求在整個網絡中使用。例如,當您訪問此博客文章時,您的 Web 瀏覽器向 Dataquest Web 伺服器發出請求,該伺服器以該網頁的內容進行響應。
API 請求的工作方式完全相同——您向 API 伺服器發出數據請求,它會響應您的請求。
在 Python 中發出 API 請求
為了在 Python 中使用 API,我們需要能夠發出這些請求的工具。在 Python 中,用於發出請求和使用 API 的最常見庫是requests庫。requests 庫不是標準 Python 庫的一部分,因此您需要安裝它才能開始使用。
如果您使用 pip 來管理您的 Python 包,您可以使用以下命令安裝請求:
pip install requests
如果你使用 conda,你需要的命令是:
conda install requests
安裝庫後,您需要導入它。讓我們從重要的一步開始:
import requests
現在我們已經安裝並導入了 requests 庫,讓我們開始使用它。
發出我們的第一個 API 請求
有許多不同類型的請求。最常用的一種是GET請求,用於檢索數據。因為我們將只處理檢索數據,所以我們的重點將放在發出“獲取”請求上。
當我們發出請求時,來自 API 的響應帶有一個響應代碼,告訴我們我們的請求是否成功。響應代碼很重要,因為如果出現問題,它們會立即告訴我們。
要發出“GET”請求,我們將使用requests.get()函數,它需要一個參數——我們要向其發出請求的 URL。我們將從向不存在的 API 端點發出請求開始,這樣我們就可以看到響應代碼的樣子。
response = requests.get("https://api.open-notify.org/this-api-doesnt-exist")
該get()函數返回一個response對象。我們可以使用該response.status_code屬性來接收我們請求的狀態碼:
print(response.status_code)
404
您可能對“404”狀態碼很熟悉——它是伺服器在找不到我們請求的文件時返回的狀態碼。在這種情況下,我們詢問了this-api-doesnt-exist哪個(驚喜,驚喜)不存在!
讓我們進一步了解一些常見的狀態碼。
API 狀態碼
向 Web 伺服器發出的每個請求都會返回狀態代碼。狀態代碼指示有關請求發生情況的信息。以下是一些與GET請求相關的代碼:
- 200: 一切順利,結果已返回(如果有)。
- 301:伺服器將您重定向到不同的端點。當公司切換域名或更改端點名稱時,可能會發生這種情況。
- 400: 伺服器認為你提出了錯誤的請求。當您不發送正確的數據時,可能會發生這種情況。
- 401: 伺服器認為你沒有通過身份驗證。許多 API 需要登錄憑證,因此當您沒有發送正確的憑證來訪問 API 時會發生這種情況。
- 403:您嘗試訪問的資源被禁止:您沒有合適的權限來查看它。
- 404: 在伺服器上找不到您嘗試訪問的資源。
- 503:伺服器尚未準備好處理請求。
您可能會注意到所有以“4”開頭的狀態代碼都表示某種錯誤。狀態代碼的第一個數字表示它們的分類。這很有用——您可以知道,如果您的狀態代碼以“2”開頭,則表示成功,如果以“4”或“5”開頭,則表示錯誤。如果您有興趣,可以在此處閱讀有關狀態代碼的更多信息。
API 文檔
為了確保我們發出成功的請求,當我們使用 API 時,查閱文檔很重要。文檔起初看起來很嚇人,但是隨著您越來越多地使用文檔,您會發現它變得越來越容易。
我們將使用開放通知API,它可以訪問有關國際空間站的數據。這是一個很棒的學習 API,因為它的設計非常簡單,並且不需要身份驗證。我們將在後面的文章中教您如何使用需要身份驗證的 API。
通常在特定伺服器上會有多個 API 可用。這些 API 中的每一個通常稱為端點。我們將使用的第一個端點是http://api.open-notify.org/astros.json,它返回有關當前在太空中的宇航員的數據。
如果您單擊上面的鏈接查看此端點的文檔,您會看到它說此 API 不接受任何輸入。這使它成為我們開始使用的簡單 API。我們將首先使用 requests 庫向端點發出 GET 請求:
response = requests.get("https://api.open-notify.org/astros.json")
print(respons
200
我們收到一個“200”代碼,告訴我們請求成功。文檔告訴我們,我們將獲得的 API 響應是 JSON 格式。在下一節中,我們將學習 JSON,但首先讓我們使用response.json() 方法來查看我們從 API 收到的數據:
print(response.json())
T{'message': 'success', 'people': [{'name': 'Alexey Ovchinin', 'craft': 'ISS'}, {'name': 'Nick Hague', 'craft': 'ISS'}, {'name': 'Christina Koch', 'craft': 'ISS'}, {'name': 'Alexander Skvortsov', 'craft': 'ISS'}, {'name': 'Luca Parmitano', 'craft': 'ISS'}, {'name': 'Andrew Morgan', 'craft': 'ISS'}], 'number': 6}
在 Python 中處理 JSON 數據
JSON(JavaScript Object Notation)是 API 的語言。JSON 是一種對數據結構進行編碼的方法,可確保它們易於被機器讀取。JSON 是數據在 API 中來回傳遞的主要格式,大多數 API 伺服器將以 JSON 格式發送它們的響應。
您可能已經註意到,我們從 API 收到的 JSON 輸出看起來像是包含 Python 字典、列表、字符串和整數。您可以將 JSON 視為表示為字符串的這些對象的組合。讓我們看一個簡單的例子:
jsonPython 對包有很好的 JSON 支持。這個json包是標準庫的一部分,所以我們不需要安裝任何東西來使用它。我們既可以將列表和字典轉換為 JSON,也可以將字符串轉換為列表和字典。對於我們的 ISS Pass 數據,它是一個字典,編碼為 JSON 格式的字符串。
json 庫有兩個主要功能:
- json.dumps()— 接收一個 Python 對象,並將其轉換(轉儲)為字符串。
- json.loads()— 獲取 JSON 字符串,並將其轉換(加載)為 Python 對象。
該dumps()函數特別有用,因為我們可以使用它來打印格式化的字符串,從而更容易理解 JSON 輸出,就像我們在上圖中看到的那樣:
import json
def jprint(obj):
# create a formatted string of the Python JSON object
text = json.dumps(obj, sort_keys=True, indent=4)
print(text)
jprint(response.json())
T{
"message": "success",
"number": 6,
"people": [
{
"craft": "ISS",
"name": "Alexey Ovchinin"
},
{
"craft": "ISS",
"name": "Nick Hague"
},
{
"craft": "ISS",
"name": "Christina Koch"
},
{
"craft": "ISS",
"name": "Alexander Skvortsov"
},
{
"craft": "ISS",
"name": "Luca Parmitano"
},
{
"craft": "ISS",
"name": "Andrew Morgan"
}
]
}
立即我們可以更容易地理解數據的結構——我們可以看到他們目前有六個人在太空中,他們的名字作為字典存在於一個列表中。
如果我們將其與端點的文檔進行比較,我們將看到它與端點的指定輸出相匹配。
使用帶有查詢參數的 API
我們之前使用的 http://api.open-notify.org/astros.json 端點不帶任何參數。我們只需發送一個 GET 請求,API 就會發回有關當前在太空中的人數的數據。
然而,擁有一個要求我們指定參數的 API 端點是很常見的。https://api.open-notify.org/iss-pass.json 端點就是一個例子。這個端點告訴我們下一次國際空間站將經過地球上的給定位置。
如果我們查看文檔,它指定了必需的lat(緯度)和long(經度)參數。
我們可以通過params在我們的請求中添加一個可選的關鍵字參數來做到這一點。我們可以用這些參數製作一個字典,然後將它們傳遞給requests.get函數。這是我們的字典的樣子,使用紐約市的坐標:
parameters = {
"lat": 40.71,
"lon": -74
}
我們也可以通過直接將參數添加到 URL 來直接做同樣的事情。像這樣:
https://api.open-notify.org/iss-pass.json?lat=40.71&lon;=-74
將參數設置為字典幾乎總是更可取的,因為requests它會處理一些出現的事情,例如正確格式化查詢參數,並且我們不需要擔心將值插入 URL 字符串。
讓我們使用這些坐標發出請求,看看我們得到什麼響應。
response = requests.get("https://api.open-notify.org/iss-pass.json", params=parameters)
jprint(response.json())
{
"message": "success",
"request": {
"altitude": 100,
"datetime": 1568062811,
"latitude": 40.71,
"longitude": -74.0,
"passes": 5
},
"response": [
{
"duration": 395,
"risetime": 1568082479
},
{
"duration": 640,
"risetime": 1568088118
},
{
"duration": 614,
"risetime": 1568093944
},
{
"duration": 555,
"risetime": 1568099831
},
{
"duration": 595,
"risetime": 1568105674
}
]
}
了解通過時間
JSON 響應與文檔指定的內容相匹配:
- 具有三個鍵的字典
- 第三個鍵 ,response包含通過時間列表
- 每個傳遞時間都是一個帶有risetime(傳遞開始時間)和duration鍵的字典。
讓我們從 JSON 對像中提取通過時間:
pass_times = response.json()['response']
jprint(pass_times)
[
{
"duration": 395,
"risetime": 1568082479
},
{
"duration": 640,
"risetime": 1568088118
},
{
"duration": 614,
"risetime": 1568093944
},
{
"duration": 555,
"risetime": 1568099831
},
{
"duration": 595,
"risetime": 1568105674
}
]
接下來我們將使用一個循環來僅提取五個 risetime 值:
risetimes = []
for d in pass_times:
time = d['risetime']
risetimes.append(time)
print(risetimes)
[1568082479, 1568088118, 1568093944, 1568099831, 1568105674]
這些時間很難理解——它們採用一種稱為時間戳或紀元的格式。本質上,時間是以 1970 年 1 月 1 日以來的秒數來衡量的。我們可以使用 Pythondatetime.fromtimestamp()方法將這些轉換為更易於理解的時間:
from datetime import datetime
times = []
for rt in risetimes:
time = datetime.fromtimestamp(rt)
times.append(time)
print(time)
2019-09-09 21:27:59
2019-09-09 23:01:58
2019-09-10 00:39:04
2019-09-10 02:17:11
2019-09-10 03:54:34
看起來國際空間站經常經過紐約市——接下來的五次發生在七小時內!
Python API 教材:後續步驟
在本教材中,我們學習了:
- 什麼是 API
- 請求類型和響應代碼
- 如何提出獲取請求
- 如何使用參數發出請求
- 如何從 API 中顯示和提取 JSON 數據
這些基本步驟將幫助您開始使用 API。請記住,每次我們使用 API 的關鍵是仔細閱讀 API 文檔並使用它來了解要發出什麼請求以及要提供什麼參數。
現在您已經完成了我們的 Python API 教材,您可能希望:
- 完成我們的交互式 Dataquest API 和抓取課程,您可以免費開始。
- 嘗試使用此免費公共 API列表中的一些數據——我們建議選擇一個不需要身份驗證的 API 作為良好的第一步。
- 試試我們的中級 API 教材,其中包括 API 身份驗證、分頁和速率限制