python数据采集4-使用API
python数据采集4-使用API
API概述
API 就是
应用编程接口(Application Programming Interface,API)
它们为不同的应
用提供了方便友好的接口。不同的开发者用不同的架构,甚至不同的语言编写软件都没问
题——因为 API 设计的目的就是要成为一种通用语言,让不同的软件进行信息共享。
浏览器输入下面
http://freegeoip.net/json/50.78.253.58
返回下面的数据
{
"ip": "50.78.253.58",
"country_code": "US",
"country_name": "United States",
"region_code": "MA",
"region_name": "Massachusetts",
"city": "Boston",
"zip_code": "02116",
"time_zone": "America/New_York",
"latitude": 42.3496,
"longitude": -71.0746,
"metro_code": 506
}
你可能会想,这不就是在浏览器窗口输入一个网址,按回车后获取的(只是 JSON 格式)
信息吗?究竟 API 和普通的网址访问有什么区别呢?如果不考虑 API 高大上的名称,其实
两者没啥区别。API 可以通过 HTTP 协议下载文件,和 URL 访问网站获取数据的协议一
样,它几乎可以实现所有在网上干的事情。API 之所以叫 API 而不是叫网站的原因,其实
是首先 API 请求使用非常严谨的语法,其次 API 用 JSON 或 XML 格式表示数据,而不是
HTML 格式
API通用规则
和大多数网络数据采集的方式不同,API 用一套非常标准的规则生成数据,而且生成的数
据也是按照非常标准的方式组织的。因为规则很标准,所以一些简单、基本的规则很容易
学,可以帮你快速地掌握任意 API 的用法。
不过并非所有 API 都很简单,有些 API 的规则比较复杂,因此第一次使用一个 API 时,建
议阅读文档,无论你对以前用过的 API 是多么熟悉。
方法
利用 HTTP 从网络服务获取信息有四种方式:
- GET
- POST
- PUT
- DELETE
GET
就是你在浏览器中输入网址浏览网站所做的事情。当你访问 http://freegeoip.net/
json/50.78.253.58 时,就会使用 GET 方法。可以想象成 GET 在说:“喂,网络服务器,请按
照这个网址给我信息。”
POST
基本就是当你填写表单或提交信息到网络服务器的后端程序时所做的事情。每次当你
登录网站的时候,就是通过用户名和(有可能加密的)密码发起一个 POST 请求。如果你用
API 发起一个 POST 请求,相当于说“请把信息保存到你的数据库里”。
PUT
在网站交互过程中不常用,但是在 API 里面有时会用到。 PUT 请求用来更新一个对象
或信息。例如,API 可能会要求用 POST 请求创建新用户,但是如果你要更新老用户的邮箱
地址,就要用 PUT 请求了。
DELETE
用于删除一个对象。例如,如果我们向 http://myapi.com/user/23 发出一个 DELETE 请
求,就会删除 ID 号是 23 的用户。 DELETE 方法在公共 API 里面不常用,它们主要用于创建
信息,不能随便让一个用户去删掉数据库的信息。但是,和 PUT 方法一样, DELETE 方法也
值得了解一下。
虽然在 HTTP 规范里还有一些信息处理方式,但是这四种基本是你使用 API 过程中可能遇
到的全部。
其实,很多 API 在更新信息的时候都是用 POST 请求代替 PUT 请求。究竟是创建一个新实体还是更新
一个旧实体,通常要看 API 请求本身是如何构建的。不过,掌握两者的差异还是有好处的,用 API
的时候你经常会遇到 PUT 请求。
验证
有些 API 要求客户验证是为了计算 API 调用的费用,或者是提供了包月的服务。有些验证
是为了“限制”用户使用 API(限制每秒钟、每小时或每天 API 调用的次数),或者是限
制一部分用户对某种信息或某类 API 的访问。还有一些 API 可能不要求验证,但是可能会为了市场营销而跟踪用户的使用行为。
例如,调用 The Echo Nest 音乐平台的 API 获取枪与玫瑰乐队(Guns N’Roses)的歌曲:
http://developer.echonest.com/api/v4/artist/songs?api_key=<你的api_key>
%20&name=guns%20n%27%20roses&format=json&start=0&results=100
这个链接向服务器提供的 api_key 是我注册之后得到的,服务器会识别出这个链接发起的
是 Ryan Mitchell(我)的请求,然后向请求者提供 JSON 格式的数据。
令牌除了在 URL 链接中传递,还会通过请求头里的 cookie 把用户信息传递给服务器。我
们将在本章后面和第 12 章更加详细地介绍请求头的内容,这里仅做简单的演示,请求头
可以用前几章使用的 urllib 包进行传递。
token = "<your api key>"
webRequest = urllib.request.Request("http://myapi.com", headers={"token":token})
html = urlopen(webRequest)
服务器响应
API 有一个重要的特征是它们会反馈格式友好
的数据。大多数反馈的数据格式都是 XML 和 JSON。
这几年,JSON 比 XML 更受欢迎,主要有两个原因。首先,JSON 文件比完整的 XML 格
式小。比如下面的 XML 数据用了 98 个字符:
<user><firstname>Ryan</firstname><lastname>Mitchell</lastname><username>Kludgist
</username></user>
同样的 JSON 格式数据:
{"user":{"firstname":"Ryan","lastname":"Mitchell","username":"Kludgist"}}
只要用 73 个字符,比表述同样内容的 XML 文件要小 36%。
JSON 格式比 XML 更受欢迎的另一个原因是网络技术的改变。过去,服务器端用 PHP
和 .NET 这些程序作为 API 的接收端。现在,服务器端也会用一些 JavaScript 框架作为 API
的发送和接收端,像 Angular 或 Backbone 等。虽然服务器端的技术无法预测它们即将收到
的数据格式,但是像 Backbone 之类的 JavaScript 库处理 JSON 比处理 XML 要更简单。
虽然大多数 API 都支持 XML 数据格式,但在本书中我们还是用 JSON 格式。当然,如果
你还没有把两种格式都掌握,那么现在熟悉它们是个好时机——短期内它们都不会消失。
解析JSON数据
我用过 freegeoip.net 网站 IP 查询的例子,可以把 IP 地址解析转换成地
理位置:
http://freegeoip.net/json/50.78.253.58
我可以获取这个请求的反馈数据,然后用 Python 的 JSON 解析函数来解码
# -*- coding: utf-8 -*-
"""
Created on Mon Jan 29 22:37:29 2018
@author: szm
"""
import json
from urllib.request import urlopen
def getCountry(ipAddress):
response = urlopen("http://freegeoip.net/json/"+ipAddress).read().decode('utf-8')
responseJson = json.loads(response)
return responseJson.get("country_code")
print(getCountry("50.78.253.58"))
返回结果如下
US
这里用的 JSON 解析库是 Python 标准库的一部分。只需要在代码开头写上 import json ,
你就可以使用它了!不同于那些需要先把 JSON 解析成一种 JSON 对象或 JSON 节点的语
言,Python 使用了一种更加灵活的方式,把 JSON 转换成字典,JSON 数组转换成列表,JSON 字符串转换成 Python 字符串。通过这种方式,就可以让 JSON 的获取和操作变得非
常简单。
下面的例子演示了如何使用 Python 的 JSON 解析库,处理 JSON 字符串中可能出现的不同
数据类型:
# -*- coding: utf-8 -*-
"""
Created on Mon Jan 29 22:37:29 2018
@author: szm
"""
import json
jsonString = '{"arrayOfNums":[{"number":0},{"number":1},{"number":2}],"arrayOfFruits":[{"fruit":"apple"},{"fruit":"banana"},{"fruit":"pear"}]}'
jsonObj = json.loads(jsonString)
print(jsonObj.get("arrayOfNums"))
print(jsonObj.get("arrayOfNums")[1])
print(jsonObj.get("arrayOfNums")[1].get("number")+jsonObj.get("arrayOfNums")[2].get("number"))
print(jsonObj.get("arrayOfFruits")[2].get("fruit"))
返回结果
[{'number': 0}, {'number': 1}, {'number': 2}]
{'number': 1}
3
pear
第一行是一个组词典构成的列表对象,第二行是一个词典对象,第三行是一个整数(第一
行词典列表里整数的和),第四行是一个字符串。
🐳 作者:hiszm 📢 版权:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,万分感谢。 💬 留言:同时 , 如果文中有什么错误,欢迎指出。以免更多的人被误导。 |