推荐一个国外讲解,很棒,详细全面,容易理解
https://www.dataquest.io/blog/python-api-tutorial/
以下是其网页翻译,以供参考,想和小哥说一下转一下的他的文,但评论区加载不出来,,
Python API教程 - 使用API的简介
Vik Paruchuri 2015年9月8日 在教程中
应用程序接口或API通常用于从远程站点检索数据。像网站reddit的,Twitter的,和Facebook的全部通过他们的API提供了一定的数据。要使用API,您向远程Web服务器发出请求,并检索所需的数据。
但是为什么要使用API而不是可以下载的静态数据集?API在以下情况下很有用:
在上述情况下,API是正确的解决方案。在这篇博文中,我们将会查询一个简单的API来检索有关国际空间站(ISS)的数据。使用API将节省我们自己做所有计算的时间和精力。
国际空间站。
API托管在Web服务器上。当您键入www.google.com
浏览器的地址栏时,您的计算机实际上是要求www.google.com
服务器找到一个网页,然后返回到浏览器。
API的工作方式相同,除了您的Web浏览器要求网页,您的程序要求数据。此数据通常以JSON格式返回(有关更多信息,请参阅我们关于使用JSON数据的教程)。
为了获取数据,我们向Web服务器发出请求。服务器然后回复我们的数据。在Python中,我们将使用请求库来执行此操作。在这个Python API教程中,我们将为所有示例使用Python 3.4。
有许多不同类型的请求。最常用的一个GET请求被用于检索数据。
我们可以使用简单的GET请求从OpenNotify API中检索信息。
OpenNotify有几个API端点。端点是用于从API检索不同数据的服务器路由。例如,/comments
Reddit API上的端点可能会检索有关注释的信息,而/users
端点可能会检索有关用户的数据。要访问它们,您可以将端点添加到API 的基本URL。
我们将在OpenNotify上看到的第一个端点是iss-now.json
端点。该端点获得国际空间站的当前纬度和经度。如您所见,检索此数据并不适合数据集,因为它涉及服务器上的一些计算,并且可以快速更改。
您可以在这里查看OpenNotify上所有端点的列表。
OpenNotify API 的基本URL是http://api.open-notify.org
,因此我们将其添加到所有端点的开头。
# Make a get request to get the latest position of the international space station from the opennotify api.
response = requests.get("http://api.open-notify.org/iss-now.json")
# Print the status code of the response.
print(response.status_code)
200
我们刚才提出的请求一个状态代码的200
。每个向Web服务器发出的请求都返回状态码。状态代码指示有关请求发生的情况的信息。以下是与GET请求相关的一些代码:
200
- 一切顺利,结果已经退回(如果有)301
- 服务器正在将您重定向到不同的端点。当公司切换域名或更改端点名称时,可能会发生这种情况。401
- 服务器认为您没有通过身份验证。当您没有发送正确的凭据来访问API时,会发生这种情况(稍后我们将讨论认证)。400
- 服务器认为您提出了错误的请求。当您不发送正确的数据时,可能会发生这种情况。403
- 您尝试访问的资源被禁止 - 您没有正确的权限来查看。404
- 您尝试访问的资源在服务器上找不到。我们现在将http://api.open-notify.org/iss-pass
根据API文档向不存在的端点发出GET请求。
response = requests.get("http://api.open-notify.org/iss-pass")
print(response.status_code)
404
iss-pass
不是有效的端点,所以我们得到一个404
状态代码作为响应。.json
正如API文档所述,我们忘记添加到最后。
我们现在将发出GET请求http://api.open-notify.org/iss-pass.json
。
response = requests.get("http://api.open-notify.org/iss-pass.json")
print(response.status_code)
400
你会看到在最后一个例子中,我们得到一个400
状态代码,这表示一个不好的请求。如果您查看OpenNotify API的文档,我们看到ISS Pass端点需要两个参数。
当ISS下一次通过地球上的给定位置时,ISS Pass端点返回。为了计算这个,我们需要将位置的坐标传递给API。我们通过传递两个参数(纬度和经度)来做到这一点。
我们可以通过params
在我们的请求中添加可选的关键字参数来实现。在这种情况下,我们需要通过两个参数:
lat
- 我们想要的位置的纬度。lon
- 我们想要的位置的经度。我们可以用这些参数制作一个字典,然后将它们传递给requests.get
函数。
我们也可以通过向url添加查询参数直接执行相同的操作,如下所示:http://api.open-notify.org/iss-pass.json?lat=40.71&lon=-74
。
将参数设置为字典几乎总是比较适合,因为requests
需要处理某些事情,比如正确格式化查询参数。
我们将使用纽约市的坐标来提出请求,看看我们得到什么回应。
# Set up the parameters we want to pass to the API.
# This is the latitude and longitude of New York City.
parameters = {"lat": 40.71, "lon": -74}
# Make a get request with the parameters.
response = requests.get("http://api.open-notify.org/iss-pass.json", params=parameters)
# Print the content of the response (the data the server returned)
print(response.content)
# This gets the same data as the command above
response = requests.get("http://api.open-notify.org/iss-pass.json?lat=40.71&lon=-74")
print(response.content)
b'{\n "message": "success", \n "request": {\n "altitude": 100, \n "datetime": 1441417753, \n "latitude": 40.71, \n "longitude": -74.0, \n "passes": 5\n }, \n "response": [\n {\n "duration": 330, \n "risetime": 1441445639\n }, \n {\n "duration": 629, \n "risetime": 1441451226\n }, \n {\n "duration": 606, \n "risetime": 1441457027\n }, \n {\n "duration": 542, \n "risetime": 1441462894\n }, \n {\n "duration": 565, \n "risetime": 1441468731\n }\n ]\n}'
b'{\n "message": "success", \n "request": {\n "altitude": 100, \n "datetime": 1441417753, \n "latitude": 40.71, \n "longitude": -74.0, \n "passes": 5\n }, \n "response": [\n {\n "duration": 329, \n "risetime": 1441445639\n }, \n {\n "duration": 629, \n "risetime": 1441451226\n }, \n {\n "duration": 606, \n "risetime": 1441457027\n }, \n {\n "duration": 542, \n "risetime": 1441462894\n }, \n {\n "duration": 565, \n "risetime": 1441468731\n }\n ]\n}'
纽约ISS。
使用JSON数据
您可能已经注意到,早期响应的内容是string
(虽然它被显示为bytes
对象,我们可以使用response.content.decode("utf-8")
)轻松地将内容转换为字符串。
字符串是我们将信息传递给API的方式,但很难从中获取我们想要的信息。我们如何知道如何解码我们得到的字符串,并在Python中使用它?我们如何altitude
从字符串响应中找出ISS?
幸运的是,有一种称为JavaScript对象表示法(JSON)的格式。JSON是将数据结构(如列表和字典)编码为字符串的方法,以确保它们易于被机器读取。JSON是将数据传递到API的主要格式,大多数API服务器将以JSON格式发送其响应。
Python具有极大的JSON支持,包含该json
包。该json
包是标准库的一部分,因此我们不需要安装任何东西来使用它。我们可以将列表和字典转换为JSON,并将字符串转换为列表和字典。在我们的ISS Pass数据的情况下,它是以JSON格式编码为字符串的字典。
json库有两个主要方法:
dumps
- 使用Python对象,并将其转换为字符串。loads
- 获取JSON字符串,并将其转换为Python对象。# Make a list of fast food chains.
best_food_chains = ["Taco Bell", "Shake Shack", "Chipotle"]
# This is a list.
print(type(best_food_chains))
# Import the json library
import json
# Use json.dumps to convert best_food_chains to a string.
best_food_chains_string = json.dumps(best_food_chains)
# We've successfully converted our list to a string.
print(type(best_food_chains_string))
# Convert best_food_chains_string back into a list
print(type(json.loads(best_food_chains_string)))
# Make a dictionary
fast_food_franchise = {
"Subway": 24722,
"McDonalds": 14098,
"Starbucks": 10821,
"Pizza Hut": 7600
}
# We can also dump a dictionary to a string and load it.
fast_food_franchise_string = json.dumps(fast_food_franchise)
print(type(fast_food_franchise_string))
您可以通过使用.json()
响应方法获取响应的内容作为python对象。
# Make the same request we did earlier, but with the coordinates of San Francisco instead.
parameters = {"lat": 37.78, "lon": -122.41}
response = requests.get("http://api.open-notify.org/iss-pass.json", params=parameters)
# Get the response data as a python object. Verify that it's a dictionary.
data = response.json()
print(type(data))
print(data)
{'response': [{'risetime': 1441456672, 'duration': 369}, {'risetime': 1441462284, 'duration': 626}, {'risetime': 1441468104, 'duration': 581}, {'risetime': 1441474000, 'duration': 482}, {'risetime': 1441479853, 'duration': 509}], 'message': 'success', 'request': {'latitude': 37.78, 'passes': 5, 'longitude': -122.41, 'altitude': 100, 'datetime': 1441417753}}
服务器不仅在生成响应时发送状态代码和数据。它还发送包含有关如何生成数据以及如何解码数据的元数据。这被存储在响应头中。在Python中,我们可以使用headers
响应对象的属性来访问它。
标题将显示为字典。在标题中,content-type
是现在最重要的关键。它告诉我们响应的格式,以及如何解码。对于OpenNotify API,格式为JSON,这就是为什么我们可以在json
之前的包中解码它。
# Headers is a dictionary
print(response.headers)
# Get the content-type from the dictionary.
print(response.headers["content-type"])
{'server': 'gunicorn/19.3.0', 'content-length': '520', 'content-type': 'application/json', 'date': 'Sat, 05 Sep 2015 01:49:13 GMT', 'connection': 'keep-alive', 'via': '1.1 vegur'}
OpenNotify还有一个API端点astros.json
。它告诉你有多少人目前在太空。答复的格式可以在这里找到。
# Get the response from the API endpoint.
response = requests.get("http://api.open-notify.org/astros.json")
data = response.json()
# 9 people are currently in space.
print(data["number"])
print(data)
9
{'number': 9, 'people': [{'name': 'Gennady Padalka', 'craft': 'ISS'}, {'name': 'Mikhail Kornienko', 'craft': 'ISS'}, {'name': 'Scott Kelly', 'craft': 'ISS'}, {'name': 'Oleg Kononenko', 'craft': 'ISS'}, {'name': 'Kimiya Yui', 'craft': 'ISS'}, {'name': 'Kjell Lindgren', 'craft': 'ISS'}, {'name': 'Sergey Volkov', 'craft': 'ISS'}, {'name': 'Andreas Mogensen', 'craft': 'ISS'}, {'name': 'Aidyn Aimbetov', 'craft': 'ISS'}], 'message': 'success'}
现在,您已经完成了Python API教程,现在应该能够访问一个简单的API并发出get
请求。还有其他几种类型requests
,您可以在我们的数据查询API和刮擦课程中了解更多关于API认证的信息。
其他推荐的下一步是阅读请求文档,并使用Reddit API。有一个叫做PRAW 的包,它使Python中的Reddit API变得更加容易,但是建议您先使用它requests
来了解一切的工作原理。
图片来源:来自名词项目的JonathanCoutiño的Web API。