python网站框架requestpostgetpatch_[Python]使用requests包进行HTTP交互方法详解

简介

Python的HTTP包有urllib、urllib2、httplib等,但是都需要了解较多的HTTP原理才能编码,借助requests包可以在较高的抽象层次上完成HTTP交互过程的开发。安装requests使用pip install requests命令,requests包内嵌了urllib3,自动支持HTTP长连接、连接池等功能。

使用方法

requests支持HTTP的HEAD、GET、POST、PUT、OPTIONS、DELETE、PATCH等请求:

变量r是一个requests.models.Response类型的响应对象,通过r可以得到HTTP响应的所有信息。

传递QUERY参数

在URI的query部分传递参数,可以直接按照标准放在URL字符串中(允许为同一个key赋值多个value):

也可以放在请求的params参数中:

使用字典做参数时,对同一个key的多个value要放在列表中,如果某个key对应的值为None,则其不会放在query中。

定制请求头

为HTTP请求报文的头部添加内容,可以请求时为headers参数赋值:

填写cookie

cookie可以以字典的形式赋值给cookies参数:

通过RequestsCookieJar对象可以设置cookie的域、path等信息:

http://httpbin.org/cookies提供的服务是:如果请求包含cookie的话,会在响应体中回应cookie内容,所以上述代码返回:

因为password在/else这个path,所以通过/cookies无法访问key为password的cookie项。

填充请求体

如果采用application/x-www-form-urlencoded格式发送HTTP请求,可以将请求内容放在data参数中。如果采用application/json格式请求,可以将内容(dict类型)放在json参数中,或者将字典转化为JSON字符串之后传给data参数,同时指定content-type为application/json:

如果需要上传文件,直接将文件以'rb'模式打开放入字典(必须使用'rb'模式,requests才能自动推算出正确的content-length),然后传入files参数,请求类型会自动转换为multipart/form-data:

需要上传的文件大小超过内存时,可以将文件的读取放在上下文管理器中,比如:

处理响应对象

从为QUERY传递参数的例子中可以看到,使用响应对象的url属性可以访问请求的URL。status_code属性可以获取响应状态码。raise_for_status方法,当状态码为4XX或5XX时,抛出对应的客户端或服务端异常,如果是2XX或3XX错误,返回None。比如:

输出可能是None,或者是:

encoding属性获取响应编码,text属性会尝试按照encoding属性自动将响应内容转码后返回,如果encoding属性为None,requests会根据chardet猜测正确的编码。针对响应内容是二进制文件(如图片)的场景,content属性获取响应的原始内容(以字节为单位),比如:

如果响应内容的大小超过了机器内存,需要分段读取响应内容,可以在请求时使用stream=True然后调用响应对象的iter_content方法:

针对application/json格式的响应内容,requests内置了json方法将结果转换为字典后返回:

如果响应内容不能转换为字典,抛出异常:ValueError: No JSON object could be decoded。

通过headers属性可以访问响应的头部。

重定向与访问历史

如果请求过程发生了重定向,requests默认返回最后一个成功的响应,如果要获取中间重定向过程的响应,可以访问history属性(按照访问先后顺序的响应对象列表),比如:

上述代码输出为:

可以发现请求先被重定向到http://localhost:5000/a,最后被重定向到http://localhost:5000/404拿到了结果。如果想禁用requests默认的处理转发的行为,可以使用allow_redirect=False,比如:

上述代码输出为:

超时

requests默认不设置超时,一直等待服务端响应。requests中将超时分为两个部分:连接超时和响应读取超时,分别表示Socket建立TCP链接超时和TCP链接建立以后,客户端读取服务端响应超时。如果设置timeout参数为一个数值,则连接超时和响应读取超时设置为同样的值,如果timeout参数是一个包含两个数值的元组,则分别代表连接超时和响应读取超时。如果过了超时时间设置以后,未成功建立TCP链接或者未成功读取服务端响应,会抛异常,比如响应读取超时的异常如下(以设置3秒超时为例):

Session对象

这里的Session是指一系列有相关意义的HTTP请求/响应的集合。使用requests.Session对象可以在多个HTTP请求之间保持变量、共用cookie、保持长连接从而提高性能(由urllib3实现)等。在请求间自动保持cookie的例子:

上述代码输出为:

通过为Session对象赋值可以在请求间提供默认值,HTTP VERB方法调用中,对于新增的值会追加,已有的值会覆盖:

服务器收到的header中'3'->'4','1'->'mars'。但是对于这种在调用时新增的方法,不会在请求间保持,比如:

代码输出为:

可以把Session对象放在上下文管理器中,这样发生异常时可以自动销毁会话,从而释放连接池中的连接,提高程序性能:

根据响应获取请求

使用响应对象的request属性可以访问响应对应的请求对象,比如:

上述代码输出可能为:

其实通过响应对象的request属性得到的是一个PreparedRequest对象,可以修改其某些属性后通过Session对象的send方法重发修改后的请求:

也可以先构造Request对象,然后调用其prepare方法返回一个PreparedRequest对象,再将该对象传给Session对象的send方法:

上述代码的输出为:

说明通过Request对象的prepare方法生成的PreparedRequest对象不会读取Session对象层次上的默认值(如cookie的设置)。Session对象的prepare_request方法也可以接受一个Request对象作为参数,返回PreparedRequest对象,但是会读取Session对象层次上的默认值(如cookie的设置):

上述代码的输出为:

SSL认证

requests默认内置了Mozilla公布的受信CA,requests默认会对服务器端SSL证书进行认证,如果证书非法会报如下错误:

如果要禁用SSL的验证,可以请求时设置verify参数为False:

依赖requests版本默认的CA的话,只有更新requests包的时候才会更新受信CA。新版本的requests会尝试使用certifi(如果使用了certifi的话,建议经常升级certifi)。

如果服务端的SSL/TLS版本与requests默认的不一致,可以借助HTTPAdapter对象更改Session对象使用的协议版本:

HTTP认证

关于HTTP认证可以阅读我的上一篇博客。

基本认证

摘要认证

上述代码的输出样例为:

代理场景

HTTP/HTTPS代理

请求时可以通过proxies参数设置代理,代理中也可以设置认证方式,比如:

SOCKS代理

SOCKS代理从传输层转发代理报文,并不关注应用层采用的是什么协议,速度一般比HTTP/HTTPS代理速度快。如果代理使用了SOCKS协议,则需要安装相应的包支持:pip install requests[socks],然后在代理的URL中按照SOCKS协议书写代理的URL即可。

你可能感兴趣的:(python网站框架requestpostgetpatch_[Python]使用requests包进行HTTP交互方法详解)