1|0简介
requests 模块是写python脚本使用频率最高的模块之一。很多人写python第一个使用的模块就是requests,因为它可以做网络爬虫。不仅写爬虫方便,在日常的开发中更是少不了requests的使用。如调用后端接口,上传文件,查询数据库等。本篇详细介绍requests的使用。
requests 是⽤Python编写的第三方库,它基于python自带网络库urllib3封装完成。采⽤Apache2 Licensed开源协议的 HTTP 库。它⽐ urllib3 更加⽅便,可以节约使用者⼤量的时间。
下面从如下6个方面,全面讲解requests模块
- 简单使用
- 请求方法
- 请求参数
- 请求返回
- 异常捕获
- 提升性能
1|1功能快速传送门
不需要看完全篇内容,直接跳转到需要查找的功能
上传文件: 请求参数->files使用
认证接口调用:请求参数->header使用
json接口调用:请求参数->json使用
form表单接口调用:请求参数->data使用
2|0requests初识
requests 是一个第三方库,使用之前需要安装。安装命令如下:
最简单请求,发送一个get请求,获得返回值。
从如上代码可以看出,使用requets发送请求只需要一行代码就可以搞定,是非常简单的事情。而requests的设计理念就是 **Requests** is an elegant and simple HTTP library for Python, built for human beings.
意思就是:requests是一个优雅而简单的 Python HTTP 库,它是为人类构建的。
由于不同版本之间参数和功能略有差异,所以说明本文使用的requests版本是 2.31.0
3|0请求方法
关于每一个请求方法的使用下面一一列举出来。以下示例基于本地启动的后端服务,尝试跑示例请更换url。
3|1get请求获取记录
3|2post请求创建记录
3|3put请求更新记录
3|4delete请求删除记录
3|5head请求获取header
从返回结果的headers中可以找到返回的数据类型 ‘Content-Type’: ‘application/json’,这说明返回的数据是json编码格式的,所以需要json反序列化之后才能使用。
3|6patch请求更新部分数据
3|7options请求查看接口要求
从返回的headers中可以看到,该接口允许的请求包括:’Allow’: ‘OPTIONS, DELETE, PUT, PATCH, HEAD, GET’,所以该接口可以使用允许的方法去访问。相反没有允许的方法是无法访问的该接口的。
4|0请求参数
request 请求的函数签名如下,可以看出requests支持非常多的参数。截止当前版本2.31.0一共16个参数。
4|1params 使用示例
功能:拼接请求url
在get请求中如果携带查询参数如分页查询
查询部分的参数有两种写法,第一是直接拼接成如上的url,另一种写法是使用params参数。
将查询的参数定义为字典,传入到params中。
请求返回对象有一个url属性,可以展示请求的方法。可以看到params将传入的字典追加到url当中。
4|2data 使用示例
功能:保存请求body体、上传文件
使用data发送一个body是json格式的请求,首先设置header中数据格式为json,然后使用json序列化body。
知识加油站
:
Content-Type字段:
header 头部信息中有一个 Content-Type 字段,该字段用于客户端告诉服务器实际发送的数据类型,比如发送的数据可以是文件、纯文本、json字符串、表单等。在requests中常用的数据类型有5种:
- application/x-www-form-urlencoded:form表单数据被编码为key/value格式发送到服务器。请求默认格式
- multipart/form-data:不仅可以传输参数,还可以传输文件
- text/xml : XML格式。发送的数据必须是xml格式
- application/json:json 格式。发送的数据必须是json格式
- text/plain :纯文本格式
form-data 提交数据的接口
某些接口需要发送multipart/form-data类型的数据,有两种方法:
- 手动组建form-data并修改headers
- 通过files参数传递form-data,推荐此种方式
手动组建form-data
通过files传递
4|3json 使用示例
功能:保存body体并json序列化
后端接口接受json格式的数据,除了使用json.dumps序列化body之后,使用json参数是更方便的选择。json参数会自动将传入的字典序列化并添加json格式的头信息。
4|4header 使用示例
功能:保存header信息,可用于伪装浏览器,携带认证信息等
公共接口为了反爬虫都会校验请求头里的信息,非浏览器的请求会被拒绝。使用特定的headers信息即可将脚本伪装成浏览器。
接口中通常需要校验认证信息,需要携带token发起请求,token就需要再headers中指定。
4|5files 使用示例
功能:上传文件
上传文件首先打开一个文件获得文件句柄,然后传入files中。可以上传一个或多个文件。
建议使用二进制的方式读取文件,requests 可能会为你提供 header 中的 Content-Length。
4|6timeout 使用示例
功能:指定请求的超时时间
超时可分为连接超时和读取超时
分别设置连接超时和读取超时,timeout=(连接超时时间, 读取超时时间)
统一设置连接超时和读取超时, timeout=超时时间
4|7hooks 使用示例
功能:添加钩子函数
Hooks即钩子方法,用于在某个流程执行时捎带执行另一个自定义的方法。
requests库只支持一个response的钩子,在响应返回时可以捎带执行我们自定义的某些方法。可以用于打印一些信息,做一些响应检查或在响应对象中添加额外的信息。
除了为某一个请求自定义钩子之外,还可以给所有请求都自定钩子函数。
5|0返回对象
每一次请求都需要获取详细准确的返回结果,requests请求返回的是一个response对象,该对象有丰富的属性和方法。
5|1content、text、json() 的区别
content 返回是的二进制的内容,text返回是字符串格式的内容,json()返回的是序列化的内容。
从以上返回结果的类型可以清晰看出三者之间的不同。通常接口返回json格式的数据比较好处理。
推荐使用:
- 确切知道接口返回的json格式的字符串,使用response.json()获取结果
- 不知道接口返回的数据格式,使用response.text获取结果
5|2status_code 和 ok
status_code 是接口的标准响应码,ok 是表示一个请求是否正常。关于正常的定义可以参见ok函数的函数说明。
接口标准响应码:
- 信息响应 (100–199)
- 成功响应 (200–299)
- 重定向消息 (300–399)
- 客户端错误响应 (400–499)
- 服务端错误响应 (500–599)
5|3reason 简要结果说明
reason 可以获取请求的简单结果描述。200的结果是200,非200的结果都会有一个简洁的说明。
5|4header 和 cookies 的展示
在调用需要登陆的接口可能需要认证之后的cookies和header中某些特殊字段,所以在请求返回中通过header和cookies拿到相应的参数。
6|0异常捕获
网络请求通常会存在很多可能的错误,特别是http请求还有复杂的后端接口。所以对于错误信息的捕获就特别重要,合理的捕获异常信息可以极大的增强代码的及健壮性。requests 提供了多种异常库,包括如下:
6|1未捕获异常
没有捕获异常,当异常发生时最后会导致程序异常退出。
6|2RequestException
RequestException 可以捕获requests请求所有的异常,是最大颗粒度的异常。
6|3ConnectionError
ConnectionError 可以捕获请求中网络相关的错误,如网络不可达,拒绝连接等。使用ConnectionError捕获到拒绝连接的错误。
6|4ConnectTimeout
请求拒绝是对端服务器收到了请求但是拒绝连接,而ConnectTimeout是没有和对端服务器建立连接而超时。
6|5ReadTimeout
ReadTimeout 是和对端服务器建立了连接,接口返回时超时。在请求接口中睡眠10s,人为制造一个读取超时。
6|6接口错误的异常处理
requests请求中所有的接口本身出错都不会抛出异常,比如接口404,500,502等都不会主动抛出异常,而是通过异常状态码展示出来。
可以看到使用最大返回的异常捕获也没有捕获到接口相关的异常,所以接口异常需要通过status_code状态码去判断。
状态码有很多,如果不想写很多if else判断语句,可以使用 response.raise_for_status() 来抛出异常。raise_for_status() 是一个类似断言assert的方法,如果请求不是200就抛出一个异常。
7|0提高请求效率的方法
7|1多线程
低效的请求:
当有大量的请求任务时使用for循环逐个遍历请求是非常低效的实现。网络IO最耗时的地方便是等待请求的返回,而for循环是顺序执行,只有在前一个请求返回之后才能继续下一个,大量的时间都浪费在网络等待中。
多线程优化:
使用多线程能够显著提高代码效率,减少请求耗时。原理是:python的多线程在遇到网络请求时会主动让CPU,所以当大量请求线程执行时,一个线程遇到网络请求就让出CPU给其他线程使用,不会阻塞等待请求返回。这样大量请求都能同一时间发送出去。
for循环请求和多线程请求对比:
可以看出多线程的耗时几乎是for循环的10分之一,将整体的请求耗时降低了一个层级。
在多线程请求时如果线程超过10个,比较推荐使用线程池的技术,能够有效减少线程的创建耗时。
7|2复用TCP链路
每调用一次requests方法请求一次目标服务器,本地机器和目标服务器之间都会建立一次TCP连接,然后传输http请求的数据。在发起大量请求的情况下建立过多的tcp连接不仅会导致代码耗时增加,而且会让目标服务器承受网络读写压力。
使用session可以做到多个请求共用一个TCP连接,在大量请求的场景下能够有效减少代码耗时和降低目标服务器压力。
使用session非常简单,只需要多做一步实例化一个session对象即可,示例如下:
普通请求和复用tcp连接请求耗时对比:
可以看出,复用TCP之后速度有更进一步的提升。
7|3重试机制
通常在一次请求中如果超时了还会重试几次,实现重试逻辑通常会使用一个记次的逻辑。可能会写出如下的代码:
其实重试的功能requests已经提供了。requests提供了一个传输适配器的方法完成一些如重试机制、心跳检测等功能能。
重试机制:
每当 Session 被初始化,就会有默认的适配器附着在 Session 上,其中一个供 HTTP 使用,另一个供 HTTPS 使用。requests允许用户创建和使用他们自己的传输适配器,实现他们需要的特殊功能。示例如下:
说明:
以上代码一共耗时20s,然后抛出异常。一次正常的请求加上三次重试,每次5s超时,所以是20s。三次之后请求还是超时,抛出timeout的异常并被捕获到。
8|0附录 resquests 最核心代码
__EOF__

本文链接:https://www.cnblogs.com/goldsunshine/p/17501390.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!