上文提到,API 是一组定义了不同软件组件之间交互的规范,交互过程中 API 可以使用不同的通信协议,其中最常用的是 HTTP。HTTP (“Hypertext Transfer Protocol”,超文本传输协议) 是一种用于在网络上发送和接收超文本的协议,它提供了一种可靠的方式来发送请求和接收响应,想象一下你使用浏览器访问一个网站,当在浏览器中输入网址并按下回车键时,浏览器会向服务器发送一个 HTTP 请求,这个请求会告诉服务器你想要浏览哪个网页或资源;当服务器接收这个请求后,会处理请求并生成一个响应,响应包含请求的内容,例如网页的 HTML 代码、图像等其他资源,服务器将响应发送回浏览器,浏览器解析响应并将内容显示在屏幕上,这种通信协议具有广泛的支持和易用性。
下面是调用 API 获取数据的流程:
GET 请求和 POST 请求是 HTTP 协议中最常见的两种请求方法,用于客户端与服务器之间的数据交互,两者的区别主要在传输安全性、传输方式、数据长度和数据缓存几个方面(由于篇幅原因,我们在这里不详细展开介绍)。
我们在调用 API 时应该根据具体的需求和安全性考虑,来选择使用 GET 请求还是 POST 请求。一般情况下如果只是获取少量数据且不涉及敏感信息,可以使用 GET 请求,如果需要向服务器提交数据,或者数据量较大,可以使用 POST 请求。
HTTP 请求是在 HTTP 协议下的一种数据格式,用于向服务器发送请求,其通常由请求行、请求头和请求体三部分构成,请求头和请求体之间用空行隔开,其中各部分包含的信息如下:
请求行 (Request Line):包括请求方法 (GET请求、POST请求等)、请求的 URL 和协议版本。
请求头 (Request Headers):包括一些关于请求的附加信息,如 User-Agent(用户代理,标识请求的客户端类型等)、Content-Type(指定请求体中发送的数据的类型)等。
请求体 (Request Body):HTTP 请求中可选的组成部分,用于向服务器传递请求所需的参数或数据,如表单数据、JSON 数据等。
GET 请求通过 URL 的查询字符串将参数传递给服务器,也就是说参数会附加在 URL 的末尾,而 POST 请求将参数放在请求体中传递给服务器,所以通常情况下 GET 请求的请求体为空,POST 请求的请求体不为空。
通常在调用 API 时需要关注公共参数、请求参数和响应参数这三种参数,其中各部分包含的信息如下:
公共参数:调用 API 时经常使用的通用参数,用于标识请求的身份、版本、签名等信息,这些参数在调用不同 API 时不会随着 API 的变化而变化。
请求参数:调用具体的 API 时需要提供的参数,用于描述请求的具体内容(如传递查询条件、分页信息等),这些参数是必需的还是可选的需要根据具体 API 的设计而定。
响应参数:API 调用成功后返回的信息,通常包括 API 调用结果的状态码、错误信息、返回的数据等。根据 API 的设计,响应参数的内容和格式可能会有不同。
公共参数和请求参数是用于发起 API 请求的,而响应参数是 API 返回的结果,需要注意一点,不同的 API 可能有不同的参数要求。
本例中需要获取浙江省粮食企业信用评价数据,根据分页数据获取接口的介绍,该 API 设计的参数如下:
参数名称 | 类型 | 说明 |
---|---|---|
appsecret | String | 用户应用识别码,通过申请获得 |
pageNum | Int | 页数 |
pageSize | Int | 每页个数(不超过200) |
上表中的参数appsecret
为公共参数,pageNum
和pageSize
为请求参数。
参数名称 | 类型 | 说明 |
---|---|---|
status | Int | 0代表失败,1代表成功 |
msg | String | 返回信息 |
data | JSON | 返回数据 |
上表中的三个参数为响应参数,用于返回请求的结果,我们只需要根据参数的名称就可以在返回的响应信息中提取相应的内容。当然在使用浙江省数据开放平台接口前,需要先完成用户注册并登录平台创建数据应用、完善应用信息,应用信息保存后即可进行接口申请,在接口申请审核通过后,就可以进行数据接口对接工作,操作流程见下图:
更加详细的注册和申请流程见官方提供的接口服务使用手册
,本文不再赘述。
如果你了解过网页爬取或 API 交互,那么你应该对 requests 库并不陌生,requests 是一个常用于发送 HTTP 请求并处理响应的 Python 库,其中requests.get()
和requests.post()
是常用的两个函数,它们分别用于发送 GET 请求和 POST 请求。
函数requests.get()
的基本用法如下:
import?requests
response?=?requests.get(url='https://api.example.com/data')
上述代码会发送一个 GET 请求到https://api.example.com/data
(即参数 url),并且将响应结果保存在变量response
中。此外该函数还有一个常用的可选参数params
用于传递查询参数,其中的参数会自动添加到 URL 中,代码如下:
params_value?=?{'key1':'value1',?'key2':'value2'}
response?=?requests.get('https://api.example.com/data',?params=params_value)
上述代码将发送 GET 请求到https://api.example.com/data?key1=value1&key2=value2
。除了参数url
和params
,函数requests.get()
还有一些其他的可选参数,比如参数headers
用于设置请求头、timeout
用于设置请求超时时间、cookies
用于设置请求的 Cookie 值等等。
函数requests.post()
的基本用法类似,除了参数url
,该函数的可选参数data
用于传递请求数据,代码如下:
import?requests
params_value?=?{'key1':'value1',?'key2':'value2'}
response?=?requests.post('https://api.example.com/data',?data=params_value)
上述代码将发送 POST 请求到https://api.example.com/data
,并将params_value
作为请求数据发送到服务器,当然也可以使用参数json
来发送 JSON 数据,若设置参数json=params_value
会自动将数据转换为 JSON 格式并发送到服务器,此外,函数requests.post()
还有其他的可选参数,这里就不多介绍了。
下面我们将分别使用 requests 库中的函数requests.get()
和requests.post()
来获取浙江省粮食企业信用评价数据,以下是 Python 代码:
import?requests
import?pandas?as?pd
#?GET?请求
def?data_get(pageNum,?pageSize,?appsecret,?url):
????'''
????pageNum:?页数
????pageSize:?每页个数(不超过200)
????appsecret:?应用识别码(申请获得)
????url:?api?接口
????'''
????#?以字典形式编辑查询参数
????parameters?=?{'pageNum':pageNum,?'pageSize':pageSize,?'appsecret':appsecret}
????#?发送?GET?请求,返回一个包含服务器响应信息的?response?对象
????response?=?requests.get(url?=?url,?params?=?parameters)
????
????#?HTTP?响应状态码为?200?表示请求成功,服务器成功处理了请求
????if?response.status_code?==?200:
????????#?响应信息中status为?1,表示成功获取数据
????????if?response.json()['status']?==?1:
????????????##?提取响应结果中返回的数据data,并转换为dataframe
????????????data?=?pd.DataFrame(response.json()['data'])
????????else:
????????????#?响应信息中status不为?1,表示获取数据失败,需进一步检查原因
????????????print(response.json())
????else:
????????#?HTTP?响应状态码不为?200?时,提示“URL未正常响应请求”
????????raise?Exception('URL未正常响应请求')
????return?data
data?=?data_get(pageNum?=?1,
?????????????????pageSize?=?200,?
?????????????????appsecret?=?'申请的?APP?识别码',?
?????????????????url?=?'http://data.zjzwfw.gov.cn/jdop_front/interfaces/cata_18444/get_data.do')
data
#?POST?请求
def?data_post(pageNum,?pageSize,?appsecret,?url):
????#?以字典形式编辑请求体
????data_value?=?{'pageNum':pageNum,?'pageSize':pageSize,?'appsecret':appsecret}
????#?发送?POST?请求,返回一个包含服务器响应信息的?response?对象
????response?=?requests.post(url?=?url,?data?=?data_value)
????
????if?response.status_code?==?200:
????????#?响应信息中status为1,表示成功获取数据
????????if?response.json()['status']?==?1:
????????????data?=?pd.DataFrame(response.json()['data'])
????????else:
????????????print(response.json())
????else:
????????raise?Exception('URL未正常响应请求')
????return?data
data?=?data_post(pageNum?=?1,?
?????????????????pageSize?=?200,?
?????????????????appsecret?=?'申请的?APP?识别码',?
?????????????????url?=?'http://data.zjzwfw.gov.cn/jdop_front/interfaces/cata_18444/get_data.do')
data?#?结果同上
使用函数requests.get()
和requests.post()
这两种请求方式得到的结果相同,该数据包含企业名称、统一社会信用代码、得分和等级四个字段,共107条数据,如下: