首页 > 编程笔记 > Python笔记 阅读:3

Python Requests库的用法(非常详细)

Requests 是一个 Python 库,用于发送和接收 HTTP 请求。它提供了简单而优雅的 API,让用户可以方便地发送各种 HTTP 请求。

本节演示的代码中使用的地址仅为示意地址,如果读者要进行实践操作,那么需要部署具备 RESTful API 功能的 Web 服务,或者选择安全的互联网服务进行替换。

Requests是什么

Requests 的目标是使用极简的方法发送 HTTP 请求以及处理响应,用户无须关注和处理一些“细枝末节”,它是目前 Python 中最常用、最受欢迎的 HTTP 工具包之一。

如下代码是 Requests 官网给出的一个示例:
>>> import requests
>>> r = requests.get('http://192.168.137.100:8000/basic-auth/user/pass', auth=('user', 'pass'))
>>> r.status_code
200
>>> r.headers['content-type']
'application/json; charset=utf8'
>>> r.encoding
'utf-8'
>>> r.text
'{"authenticated": true, ...'
>>> r.json()
{'authenticated': True, ...}
在请求过程中,函数名与 HTTP 请求方式名一致,认证处理也非常简单。在处理响应结果时,返回的结果被封装到一个对象中,该对象有着丰富的属性和方法。用户直接访问返回结果对象的属性或方法,就可以获取状态码、头部的信息、返回的文本,也可以将返回的 JSON 数据直接转换为 Python 对象。

本书使用的 Requests 版本是 2.31.0,可以使用如下命令进行安装:
pip install requests==2.31.0
Requests 工具包在网络运维自动化开发中主要被用于向网络管理平台或者 SDN 控制器发起 HTTP 请求、调用 RESTful API 获取信息或者触发自动化操作。它也被用于向网络设备发起 RESTCONF 请求、查询或者修改网络配置数据。

Requests发送GET请求

Requests 的 get() 函数用于发送 GET 请求查询信息,并将服务端返回的响应封装成 Requests 内的 Response 对象。

get() 函数主要包含以下两个参数:
Requests 可以将参数自动拼接到实际请求的 URL 中,并对一些特殊字符进行编码处理,用户对这些处理都是无感知的。Requests 会将 HTTP 请求后的响应结果封装到 Response 对象中。用户通过访问 Response 对象的属性和方法就可以获取和处理响应数据。

下表展示了 Response 对象的常用属性和方法(假设返回的数据对象赋值给 response 变量)。

表:Response对象的常用属性和方法
属性或方法 说明
response.status_code 响应的状态码,整数类型
response.headers 响应的头部信息,字典类型
response.text 响应的文本内容,字符串类型
response.content 响应的二进制内容,多用于处理图片、音频、文件等,读者仅作了解即可
response.url 请求实际访问的URL
response.json() 如果返回的响应是JSON数据,那么可以调用此方法将其转成Python对象;如果响应不是有效的JSON数据,那么可以调用此方法并抛出异常

下面实例通过 Requests 的 get() 函数发送请求并访问其响应对象,其中演示了 get() 函数不带参数和带参数的两种调用方式。
import requests
 
api_url = 'http://192.168.137.100:8000/cmdb/devices'
# 第一个参数url,要请求的地址
response = requests.get(url=api_url)
 
# 如果访问的API有参数,可以将Python字典数据赋值给params
dev = {'name': 'netdevops01', 'ip': '192.168.137.1'}
response = requests.get(url=api_url, params=dev)
 
# 查看实际访问的URL
print(response.url)
# 输出 http://192.168.137.100:8000/get?name=netdevops01&ip=192.168.137.1"
 
# 查看状态码status_code属性
print(response.status_code)  # 输出 200
 
# 查看返回的文本text属性
print(response.text)
 
# 尝试将返回的JSON字符串转换为Python对象,若转换失败,则会报错
print(response.json())

Requests发送POST请求

Requests 的 post() 函数通过 POST 请求向服务器发送数据,该函数通常用于创建或更新资源(不同 RESTful API 的实际效果会有一定差异,以服务端的 API 说明文档为准)。

在 POST 请求体中,数据的传输有表单数据和 JSON 数据两种主要形式。表单数据是用户在 Web 页面上填写相关表单后,单击“提交”按钮提交的数据,多见于比较传统的网站或者系统平台。这种方式在当今的系统对接中几乎不会出现,此处仅作演示,读者了解即可,可参考如下代码:
import requests
 
api_url = 'http://192.168.137.100:8000/cmdb/devices'
dev = {'name': 'netdevops01', 'ip': '192.168.137.1'}
 
# 通过data参数,不做任何处理发送表单数据
response = requests.post(url=api_url, data=dev)
# 请求的头部中指定了'Content-Type': 'application/x-www-form-urlencoded'
print(response.text)
Python 的字典数据对象直接赋值给 post() 方法的 data 参数,这种情况默认是以表单方式将数据发给服务端。Requests 会对 Python 对象进行编码,同时在请求的 headers 中将 Content-Type 字段赋值为 application/x-www-form-urlencoded。

Requests 的 post() 方法提供了一种发送 JSON 数据的简洁方式。用户只需要将可以转换为 JSON 数据的 Python 对象(字典或者列表类型)赋值给 post() 函数的 json 参数即可。

Requests 在 post() 方法内部帮助用户把请求的数据转换为 JSON 数据,并调整 headers 的赋值,从而简化了操作流程。

下面实例演示了 Requests 的 post() 函数发送请求传输 JSON 数据,读者务必掌握此方法:
import requests
 
api_url = 'http://192.168.137.100:8000/cmdb/devices'
dev = {'name': 'netdevops01', 'ip': '192.168.137.1'}
 
# 通过json参数,发送JSON数据
# 请求的头部当中指定了'Content-Type': 'application/json'
response = requests.post(url=api_url, json=dev)

Requests发送PUT、PATCH、DELETE请求

GET 请求与 POST 请求是两种最常见的请求,此外,用户还可能使用到 PUT 请求、PATCH 请求和 DELETE 请求。

PUT 请求与 PATCH 请求在 RESTful API 中多用于更新资源:
在 RESTful API 中,多在 URL 中指定要更新资源的 ID,然后调用 PUT 或者 PATCH 请求进行数据更新,在每次更新成功后,就会返回更新后资源的 JSON 数据。

Requests 中有 put() 函数和 patch() 函数对应上述两种请求,其使用方法与 post() 函数完全一致,此处仅作简单的代码展示。

下面实例演示了利用 Requests 的 put() 和 patch() 函数发送 PUT 请求和 PATCH 请求:
import requests
 
api_url = 'http://192.168.137.100:8000/cmdb/devices/1'
# PUT请求的资源字段是全量
dev = {'name': 'netdevops01', 'ip': '192.168.137.1'}
response = requests.put(url=api_url,json=dev)
 
api_url = 'http://192.168.137.100:8000/cmdb/devices/2'
# PATCH请求的资源字段是部分
dev = {'name': 'netdevops01'}
response = requests.patch(url=api_url,json=dev)
在 RESTful API 中,DELETE 请求用于删除资源。通常来说,如果想在 URL 中删除指定资源的 ID,只需要直接向此 URL 发送 DELETE 请求即可。成功后返回的结果状态码多为 204,返回体中的内容多为空。

下面实例演示了通过 Requests 中的 delete() 函数,就可以发送 DELETE 请求:
import requests
 
api_url = 'http://192.168.137.100:8000/cmdb/devices/2'
response = requests.delete(url=api_url)
在 RESTCONF 协议中,删除资源时需要添加待删除的配置数据,所以也可以在 delete 方法中添加 json 参数。当然,一切以服务端的 API 使用手册为准。

HTTP请求的认证及自定义认证类

在系统之间的对接过程中,为保障数据安全,RESTful API 普遍采用认证机制。这种机制旨在验证应用程序或服务是否具备访问另一应用程序或服务的权限,从而确保数据传输的合法性与安全性。

API 认证是一种验证用户身份的机制,通常需要提供用户名和密码以及其他凭证。Requests 提供了两种 API 认证方式,可以方便地与不同的服务端进行交互并完成认证:
使用 Requests 进行 API 认证的过程非常简单,只需要在发送请求的方法中传入一个 auth 参数,并指定相应的认证对象即可,这里以基本认证为例进行演示,参考如下代码:
import requests
from requests.auth import HTTPBasicAuth,
 
# 基本认证,创建HTTPBasicAuth对象,赋值给auth参数
response = requests.get('http://192.168.137.100:8000/auth',
                        auth=HTTPBasicAuth('username', 'password'))
在实际的 API 对接中,认证方式可能多种多样。如果 Requests 中的认证类不能满足用户的需求,用户也可以基于 requests.auth.AuthBase 类去编写自己的认证类。用户需要先继承这个基类,自定义初始化函数所需的参数,然后编写 __init__() 方法创建自定义认证对象的参数。

自定义类要实现 __call__() 方法,此方法的参数是固定的,只有一个 r,代表待发送的请求对象。在 __call__() 方法内部,用户要编写逻辑去完成认证所需的物料,例如 Basic Auth 是按一定规则拼凑一个字符串,将其放置到请求的头部(r 变量的 headers)中。在实际发送请求时,Requests 的方法会实例化这个认证对象并调用它的 __call__() 方法,当物料都准备好之后才会真正发送出一个请求。

下面实例演示了自定义认证类实现 Basic Auth 的认证方式:
import requests
from requests.auth import AuthBase
import base64
 
class MyAuth(AuthBase):
    def __init__(self, username, password):
        """
        此处的参数与逻辑,用户可以根据需求自行设计
        """
        self.username = username
        self.password = password
 
    def __call__(self, r):
        '''
        requests在发送请求之前会调用此对象的__call__方法
        r代表此次要发送的请求
        按照认证接口要求,通过自定义的参数进行数据加工
        在r的headers中赋值指定的key和对应的value
        返回待发送的请求r即可
        '''
        # 将用户名和密码组合编码
        s = ":".join((self.username, self.password))
        b = base64.b64encode(s.encode('utf8'))
        authstr = "Basic " + b.decode()
        # 将认证信息添加到请求的头部
        r.headers["Authorization"] = authstr
        return r
 
api_url = 'http://192.168.137.100:8000/cmdb/devices/'
# 使用自己创建的认证类构建认证对象,并赋值给调用方法的auth参数
auth_obj = MyAuth(username='user', password='passwd')
response = requests.get(url=api_url, auth=auth_obj)
上面程序只是一个简单演示。在实际生产中,读者要根据服务端的 API 手册编写认证的逻辑,例如使用指定的用户名和密码发送请求获取 token,并将 token 放置到请求头当中。

以上就是 Requests 的基本使用方法,本节仅演示了常见的请求方式、认证方式和自定义认证方式。在实际使用中,读者可能会遇到一些其他问题,可以参考官方手册来解决。

Requests 工具包主要有两种使用场景:
网络运维自动化的需求层出不穷,现有的网络管理平台可能在功能或者数据内容上无法满足读者的需求,但是借助于平台提供的 RESTful API,读者相当于拥有了原子操作,通过对原子操作的组装与编排就可以实现复杂的逻辑与功能,进而满足需求。

随着技术的不断发展,厂商的平台都非常重视 RESTful API,一般都配有详尽的官方手册,如华为、思科等规模比较大的公司。

相关文章