在对 http
的 api
测试时,或者利用 api
实现批量添加、删除等等重复的工作时,必然需要利用一个发送 http
请求的库,今天介绍一个我在使用过程中感觉相当简单的一个库– requests
安装
python -m pip install requests
requests
支持 python
的版本为 2.7 以及 3.5+
模块说明
对于发送一个 http(s)
请求,无非就是
- 发送一个请求
- 对发送结果的处理,简单可以分为下面两部分
- 发送成功后,对收到的数据处理
- 发送失败,对异常状况的处理
首先需要明确一点, requests
是在 urllib3
这个很强大的,python
自带的库的基础上进行了重新封装,并提供给用户一套更简洁,使用更方便的接口
而 request
本身大概提供哪些接口呢?
from .models import Request, Response, PreparedRequest
from .api import request, get, head, post, patch, put, delete, options
from .sessions import session, Session
from .status_codes import codes
from .exceptions import (
RequestException, Timeout, URLRequired,
TooManyRedirects, HTTPError, ConnectionError,
FileModeWarning, ConnectTimeout, ReadTimeout
)
上面这一部分主要涉及到几个可能会用到的类 Request
, Response
, PreparedRequest
, Session
其他基本都是一些函数和异常的说明
所以重点回到上面提到的 4 个类
Session
负责和对方创建连接,Request
负责封装需要发送的信息, PreparedRequest
负责对 Request
封装的信息预处理,Response
主要是请求返回的信息
也就说, Session
中创建连接,发送( send
) Request
, 得到 Response
这篇文章主要就是简单入门,不做太详细的介绍,之后有时间会完整的分析一下源码。
不要被上面 4 个类吓住了,在真正使用过程中,实际上特别简单
发送
如果看了上面的部分,会注意到
from .api import request, get, head, post, patch, put, delete, options
其实这几个函数就能实现我们发送的功能,首先解释一下几个接口
get
, head
, post
, patch
, put
, delete
, options
这些发送的类型实际上用的都是 request
接口, 无非就是调用 request
函数的时候,指定一下自己的 method
def get(url, params=None, **kwargs):
kwargs.setdefault('allow_redirects', True)
return request('get', url, params=params, **kwargs)
所以接口的重点就是 request
"""Constructs and sends a :class:`Request <Request>`.
:param method: method for the new :class:`Request` object.
:param url: URL for the new :class:`Request` object.
:param params: (optional) Dictionary, list of tuples or bytes to send
in the query string for the :class:`Request`.
:param data: (optional) Dictionary, list of tuples, bytes, or file-like
object to send in the body of the :class:`Request`.
:param json: (optional) A JSON serializable Python object to send in the body of the :class:`Request`.
:param headers: (optional) Dictionary of HTTP Headers to send with the :class:`Request`.
:param cookies: (optional) Dict or CookieJar object to send with the :class:`Request`.
:param files: (optional) Dictionary of ``'name': file-like-objects`` (or ``{'name': file-tuple}``) for multipart encoding upload.
``file-tuple`` can be a 2-tuple ``('filename', fileobj)``, 3-tuple ``('filename', fileobj, 'content_type')``
or a 4-tuple ``('filename', fileobj, 'content_type', custom_headers)``, where ``'content-type'`` is a string
defining the content type of the given file and ``custom_headers`` a dict-like object containing additional headers
to add for the file.
:param auth: (optional) Auth tuple to enable Basic/Digest/Custom HTTP Auth.
:param timeout: (optional) How many seconds to wait for the server to send data
before giving up, as a float, or a :ref:`(connect timeout, read
timeout) <timeouts>` tuple.
:type timeout: float or tuple
:param allow_redirects: (optional) Boolean. Enable/disable GET/OPTIONS/POST/PUT/PATCH/DELETE/HEAD redirection. Defaults to ``True``.
:type allow_redirects: bool
:param proxies: (optional) Dictionary mapping protocol to the URL of the proxy.
:param verify: (optional) Either a boolean, in which case it controls whether we verify
the server's TLS certificate, or a string, in which case it must be a path
to a CA bundle to use. Defaults to ``True``.
:param stream: (optional) if ``False``, the response content will be immediately downloaded.
:param cert: (optional) if String, path to ssl client cert file (.pem). If Tuple, ('cert', 'key') pair.
:return: :class:`Response <Response>` object
:rtype: requests.Response
官方的文档里介绍的有点多,我挑几个日常可能使用频率比较高的
methon
中填写请求的类型, 例如GET
,POST
,DELETE
等等,看get()
等方法里,小写也可以url
字段填写http
的正常地址- 接下来是可扩充的额外字段
header
中放一些请求的头信息, 比如指明解析方式的Content-Type:application/json
, 连接方式Connection:keep-alive
等一般都是放在header
中Post
请求中Body体的内容用data
或者json
timeout
自定义请求超时时间
示例:
import requests
req = requests.request('GET', 'https://www.baidu.com')
print(req.status_code)
因为返回的是一个 Response
对象,具体可以从中获取哪些信息,可以直接跳转到 Response
的类中查看
回复的处理
一般通信之间都会使用 json
格式, 传输数据, 假设我们这里 url
可以得到一个 json
为例:
req = requests.request('GET', 'https://www.baidu.com')
if req.status_code == 200 :
try:
res_json = req.json()
except ValueError:
print("解析失败")
这里的 req.json()
, 它实际上就是对返回的结果 req.text
做了一次 json.loads
的处理,所以最基本的做法是
req = requests.request('GET', 'https://www.baidu.com')
if req.status_code == 200 :
print(req.text)
异常
前面介绍的时候提到异常
from .exceptions import (
RequestException, Timeout, URLRequired,
TooManyRedirects, HTTPError, ConnectionError,
FileModeWarning, ConnectTimeout, ReadTimeout
)
注意一点,这里的超时也是一种异常,所以我们在发送请求时候的如果设置了 超时时间 是需要通过 try ... except
来捕获的
import requests
try:
req = requests.request('GET', 'https://github.com/',timeout=1)
except requests.exceptions.Timeout:
print("请求超时")
总结
虽然我这里写的很简单,但是发送请求的参数实际上可以实现很多功能,文件的上传下载,设置代理,Cookies
等等,感兴趣的可以查阅一下官方的文档
https://requests.readthedocs.io/
requests
使用起来很方便,功能也很强大,是个值得学习的库~