python****网络编程常用库使用手册
一、urllib3
** Urllib3****是一个功能强大,条理清晰,用于HTTP客户端的Python库,许多Python的原生系统已经开始使用urllib3。Urllib3提供了很多python标准库里所没有的重要特性:**
1、 线程安全
2、 连接池
3、 客户端SSL/TLS验证
4、 文件分部编码上传
5、 协助处理重复请求和HTTP重定位
6、 支持压缩编码
7、 支持HTTP和SOCKS代理
8、 100%测试覆盖率
下面将针对urllib3功能进行详细介绍。
<v:shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"><v:stroke joinstyle="miter"><v:formulas></v:formulas><v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"></v:path></v:stroke></v:shapetype><v:shape id="图片_x0020_1" o:spid="_x0000_i1052" type="#_x0000_t75" style="width:414.75pt;height:61.5pt;visibility:visible;mso-wrap-style:square"><v:imagedata src="file:///C:\Users\ADMINI~1\AppData\Local\Temp\msohtmlclip1\01\clip_image001.png" o:title=""></v:imagedata></v:shape>
这是一个简单的请求例子:首先使用PoolManager()生成请求,由该实例对象处理与线程池的链接及线程安全的所有细节;使用request()创建请求,其中包含请求方式及url,request()方法返回一个HTTPResponse对象;当然,request()支持添加参数,用法如下:
<v:shape id="图片_x0020_4" o:spid="_x0000_i1051" type="#_x0000_t75" style="width:327pt;height:63pt;
visibility:visible;mso-wrap-style:square"><v:imagedata src="file:///C:\Users\ADMINI~1\AppData\Local\Temp\msohtmlclip1\01\clip_image002.png" o:title=""></v:imagedata></v:shape>
直接添加参数字典即可。除了fields=参数外,还有headers={}构造请求头。
对于GET/HEAD/DELETE请求可以直接定义字典传给request()即可;
对于POST/PUT则需要对参数进行编码,然后连接至url后面,例如:
<v:shape id="图片_x0020_5" o:spid="_x0000_i1050" type="#_x0000_t75" style="width:336.75pt;height:75.75pt;
visibility:visible;mso-wrap-style:square"><v:imagedata src="file:///C:\Users\ADMINI~1\AppData\Local\Temp\msohtmlclip1\01\clip_image003.png" o:title=""></v:imagedata></v:shape>
这里引入了一个参数转querystring的方法urlencode
def url_encoding(data_): data_list = [] for k,v in data_.items(): str_ = str(k) + '=' + str(v)
data_list.append(str_)
strr = '&'.join(data_list) return strr
源码类似这样
通过定义body参数并定义headers的Content-Type参数来发送已经编译 的json数据,例如:
<v:shape id="图片_x0020_6" o:spid="_x0000_i1049" type="#_x0000_t75" style="width:372pt;height:120.75pt;
visibility:visible;mso-wrap-style:square"><v:imagedata src="file:///C:\Users\ADMINI~1\AppData\Local\Temp\msohtmlclip1\01\clip_image004.png" o:title=""></v:imagedata></v:shape>
使用nultipart/form-data编码方式上传文件可以使用和传入form-data一样的方法,并将文件定义为一个元组,例如: <v:shape id="_x0000_i1025" type="#_x0000_t75" alt="" style="width:24pt;height:24pt"> <v:shape id="图片_x0020_7" o:spid="_x0000_i1048" type="#_x0000_t75" style="width:372.75pt;
height:116.25pt;visibility:visible;mso-wrap-style:square"><v:imagedata src="file:///C:\Users\ADMINI~1\AppData\Local\Temp\msohtmlclip1\01\clip_image005.png" o:title=""></v:imagedata></v:shape></v:shape>
如果发送原始二进制数据比如图片视频等,只要定义body数据即可,同时需要对header的Content-Type参数进行设置,例如:
<v:shape id="图片_x0020_8" o:spid="_x0000_i1047" type="#_x0000_t75" style="width:318pt;height:102.75pt;
visibility:visible;mso-wrap-style:square"><v:imagedata src="file:///C:\Users\ADMINI~1\AppData\Local\Temp\msohtmlclip1\01\clip_image006.png" o:title=""></v:imagedata></v:shape>
超时设定timeout
<v:shape id="图片_x0020_9" o:spid="_x0000_i1046" type="#_x0000_t75" style="width:477.75pt;height:237.75pt;
visibility:visible;mso-wrap-style:square"><v:imagedata src="file:///C:\Users\ADMINI~1\AppData\Local\Temp\msohtmlclip1\01\clip_image007.png" o:title=""></v:imagedata></v:shape>
请求重试
原理与handles rediect一样,通过设置retries参数进行控制,urllib3默认三次请求重试,进行三次方向改变,
给retries参数定义一个整型来改变请求重试的次数:
<v:shape id="图片_x0020_10" o:spid="_x0000_i1045" type="#_x0000_t75" style="width:402.75pt;height:15.75pt;
visibility:visible;mso-wrap-style:square"><v:imagedata src="file:///C:\Users\ADMINI~1\AppData\Local\Temp\msohtmlclip1\01\clip_image008.png" o:title=""></v:imagedata></v:shape>
关闭请求重试(retrying request)及重定向(redirect)只要将retries定义为False即可:
<v:shape id="图片_x0020_11" o:spid="_x0000_i1044" type="#_x0000_t75" style="width:414.75pt;height:20.25pt;
visibility:visible;mso-wrap-style:square"><v:imagedata src="file:///C:\Users\ADMINI~1\AppData\Local\Temp\msohtmlclip1\01\clip_image009.png" o:title=""></v:imagedata></v:shape>
关闭重定向(redirect)但保持重试(retrying request),将redirect参数定义为False即可:
<v:shape id="图片_x0020_12" o:spid="_x0000_i1043" type="#_x0000_t75" style="width:342.75pt;height:64.5pt;
visibility:visible;mso-wrap-style:square"><v:imagedata src="file:///C:\Users\ADMINI~1\AppData\Local\Temp\msohtmlclip1\01\clip_image010.png" o:title=""></v:imagedata></v:shape>
4****、要进行更精细的控制,可以使用retry实例,通过该实例可以对请求的重试进行更精细的控制。例如,进行3次请求重试,但是只进行2次重定向:
<v:shape id="图片_x0020_13" o:spid="_x0000_i1042" type="#_x0000_t75" style="width:336.75pt;height:63pt;
visibility:visible;mso-wrap-style:square"><v:imagedata src="file:///C:\Users\ADMINI~1\AppData\Local\Temp\msohtmlclip1\01\clip_image011.png" o:title=""></v:imagedata></v:shape>
如果想让所有请求都遵循一个retry策略,可以在PoolManager中定义retry参数:
<v:shape id="图片_x0020_14" o:spid="_x0000_i1041" type="#_x0000_t75" style="width:407.25pt;height:111.75pt;visibility:visible;
mso-wrap-style:square"><v:imagedata src="file:///C:\Users\ADMINI~1\AppData\Local\Temp\msohtmlclip1\01\clip_image012.png" o:title=""></v:imagedata></v:shape>
二、requests
requests****库可以通过pip install直接安装,在功能与易用性方面,requests
是非常出色的。以下通过举例说明用法,参考自官方文档。
【get请求】****:
<v:shape id="图片_x0020_15" o:spid="_x0000_i1040" type="#_x0000_t75" style="width:337.5pt;height:29.25pt;visibility:visible;
mso-wrap-style:square"><v:imagedata src="file:///C:\Users\ADMINI~1\AppData\Local\Temp\msohtmlclip1\01\clip_image013.png" o:title=""></v:imagedata></v:shape>
如果需要传参,则直接在定义字典,已字典方式进行传参即可:
<v:shape id="图片_x0020_18" o:spid="_x0000_i1039" type="#_x0000_t75" style="width:414.75pt;height:44.25pt;visibility:visible;
mso-wrap-style:square"><v:imagedata src="file:///C:\Users\ADMINI~1\AppData\Local\Temp\msohtmlclip1\01\clip_image014.png" o:title=""></v:imagedata></v:shape>
请求完成可以通过r.url获得已经组合形成的URL,当然当参数中含有列表时,同样可以进行传参:
<v:shape id="图片_x0020_19" o:spid="_x0000_i1038" type="#_x0000_t75" style="width:415.5pt;height:78pt;visibility:visible;
mso-wrap-style:square"><v:imagedata src="file:///C:\Users\ADMINI~1\AppData\Local\Temp\msohtmlclip1\01\clip_image015.png" o:title=""></v:imagedata></v:shape>
以下是一个添加cookie的过程:
<v:shape id="图片_x0020_25" o:spid="_x0000_i1037" type="#_x0000_t75" style="width:415.5pt;height:87pt;visibility:visible;
mso-wrap-style:square"><v:imagedata src="file:///C:\Users\ADMINI~1\AppData\Local\Temp\msohtmlclip1\01\clip_image016.png" o:title=""></v:imagedata></v:shape>
上面的cookie添加使用了RequestsCookieJar()方法,它的行为与字典类似,但是界面更为完整,适合跨域路径使用。
【post请求】****,传参方式与get一致:
<v:shape id="图片_x0020_16" o:spid="_x0000_i1036" type="#_x0000_t75" style="width:414.75pt;height:28.5pt;visibility:visible;
mso-wrap-style:square"><v:imagedata src="file:///C:\Users\ADMINI~1\AppData\Local\Temp\msohtmlclip1\01\clip_image017.png" o:title=""></v:imagedata></v:shape>
其他请求方式:
<v:shape id="图片_x0020_17" o:spid="_x0000_i1035" type="#_x0000_t75" style="width:415.5pt;height:64.5pt;visibility:visible;
mso-wrap-style:square"><v:imagedata src="file:///C:\Users\ADMINI~1\AppData\Local\Temp\msohtmlclip1\01\clip_image018.png" o:title=""></v:imagedata></v:shape>
【返回数据处理】
当返回数据为文本时,通过r.text获得返回数据:
<v:shape id="图片_x0020_20" o:spid="_x0000_i1034" type="#_x0000_t75" style="width:414.75pt;height:51pt;visibility:visible;
mso-wrap-style:square"><v:imagedata src="file:///C:\Users\ADMINI~1\AppData\Local\Temp\msohtmlclip1\01\clip_image019.png" o:title=""></v:imagedata></v:shape>
通常编码方式是在header中已经定义好的,可以通过r.encoding查看,当你需要改变编码方式时可以直接使用r.encoding=’utf-8’来改变返回数据的编码方式。
当返回数据为二进制数据时,需要使用r.content进行返回数据获得:
<v:shape id="图片_x0020_21" o:spid="_x0000_i1033" type="#_x0000_t75" style="width:415.5pt;height:40.5pt;visibility:visible;
mso-wrap-style:square"><v:imagedata src="file:///C:\Users\ADMINI~1\AppData\Local\Temp\msohtmlclip1\01\clip_image020.png" o:title=""></v:imagedata></v:shape>
可以看到两种方式返回的数据一个为unicode,一个为bytes,看起来很像其实不一样。
其他返回有:
r.status_code 返回状态码
r.raw 返回原始响应体一个response对象可以使用r.raw.read()读取
r.headers ****返回响应头(响应头字典键不区分大小写)
r.json()
r.raise_for_status() 失败请求跑出异常
r.cookies[‘example_cookie_name’] 取得cookie
【上传文件】
以下直接举例代码:
import requests
url = 'http://127.0.0.1:5000/upload'
files = {'file': open('/home/lyb/sjzl.mpg', 'rb')}
files = {'file': ('report.jpg', open('/home/lyb/sjzl.mpg', 'rb'))} #显式的设置文件名
r = requests.post(url, files=files)
print(r.text)
已二进制方式(rb)打开文件,直接在post方式里添加文件即可上传
【身份验证】
基本身份验证(HTTP Basic Auth)
<v:shape id="图片_x0020_22" o:spid="_x0000_i1032" type="#_x0000_t75" style="width:415.5pt;height:105.75pt;visibility:visible;
mso-wrap-style:square"><v:imagedata src="file:///C:\Users\ADMINI~1\AppData\Local\Temp\msohtmlclip1\01\clip_image021.png" o:title=""></v:imagedata></v:shape>
摘要式身份认证
<v:shape id="图片_x0020_23" o:spid="_x0000_i1031" type="#_x0000_t75" style="width:415.5pt;height:55.5pt;visibility:visible;
mso-wrap-style:square"><v:imagedata src="file:///C:\Users\ADMINI~1\AppData\Local\Temp\msohtmlclip1\01\clip_image022.png" o:title=""></v:imagedata></v:shape>
Oauth1****认证
<v:shape id="图片_x0020_24" o:spid="_x0000_i1030" type="#_x0000_t75" style="width:415.5pt;height:135.75pt;visibility:visible;
mso-wrap-style:square"><v:imagedata src="file:///C:\Users\ADMINI~1\AppData\Local\Temp\msohtmlclip1\01\clip_image023.png" o:title=""></v:imagedata></v:shape>
r.status_code == requests.codes.ok****(requests附带的内置状态码查询对象)
【会话对象】
会话对象让你能够跨请求保持某些参数。它也会在同一个 Session 实例发出的所有请求之间保持 cookie, 期间使用 urllib3 的 connection pooling功能。所以如果你向同一主机发送多个请求,底层的 TCP 连接将会被重用,从而带来显著的性能提升。
以下是一个跨请求保持cookie的例子:
<v:shape id="图片_x0020_26" o:spid="_x0000_i1029" type="#_x0000_t75" style="width:415.5pt;height:87.75pt;visibility:visible;
mso-wrap-style:square"><v:imagedata src="file:///C:\Users\ADMINI~1\AppData\Local\Temp\msohtmlclip1\01\clip_image024.png" o:title=""></v:imagedata></v:shape>
先创建session,然后使用这个session进行请求,在这个session中会保存所传入的cookie。
会话还可以用作前后文管理器,这样就能确保 with 区块退出后会话能被关闭,即使发生了异常也一样:
<v:shape id="图片_x0020_27" o:spid="_x0000_i1028" type="#_x0000_t75" style="width:415.5pt;height:36.75pt;visibility:visible;
mso-wrap-style:square"><v:imagedata src="file:///C:\Users\ADMINI~1\AppData\Local\Temp\msohtmlclip1\01\clip_image025.png" o:title=""></v:imagedata></v:shape>
【请求与响应对象】
任何时候进行了类似 requests.get() 的调用,你都在做两件主要的事情。其一,你在构建一个 Request对象, 该对象将被发送到某个服务器请求或查询一些资源。其二,一旦 requests 得到一个从服务器返回的响应就会产生一个 Response 对象。该响应对象包含服务器返回的所有信息,也包含你原来创建的 Request 对象。
如果想得到发送到服务器的请求的头部,我们可以简单地访问该请求,然后是该请求的头部:
<v:shape id="图片_x0020_28" o:spid="_x0000_i1027" type="#_x0000_t75" style="width:415.5pt;height:49.5pt;visibility:visible;
mso-wrap-style:square"><v:imagedata src="file:///C:\Users\ADMINI~1\AppData\Local\Temp\msohtmlclip1\01\clip_image026.png" o:title=""></v:imagedata></v:shape>
【准备的请求(Prepared Request)】
当你从 API 或者会话调用中收到一个 Response对象时,request 属性其实是使用了 PreparedRequest。有时在发送请求之前,你需要对 body 或者 header (或者别的什么东西)做一些额外处理,下面演示了一个简单的做法:
<v:shape id="图片_x0020_29" o:spid="_x0000_i1026" type="#_x0000_t75" style="width:415.5pt;height:291.75pt;visibility:visible;
mso-wrap-style:square"><v:imagedata src="file:///C:\Users\ADMINI~1\AppData\Local\Temp\msohtmlclip1\01\clip_image027.png" o:title=""></v:imagedata></v:shape>