观音披萨 發表於 2020-4-29 14:02:00

Python urllib3模块详解

<p>Urllib3是一个功能强大,条理清晰,用于HTTP客户端的Python库,许多Python的原生系统已经开始使用urllib3。Urllib3提供了很多python标准库里所没有的重要特性:</p>
<p> &nbsp; &nbsp;1、&nbsp;线程安全</p>
<p>  2、&nbsp;连接池</p>
<p>  3、&nbsp;客户端SSL/TLS验证</p>
<p>  4、&nbsp;文件分部编码上传</p>
<p>  5、&nbsp;协助处理重复请求和HTTP重定位</p>
<p>  6、&nbsp;支持压缩编码</p>
<p>  7、&nbsp;支持HTTP和SOCKS代理</p>
<p>  8、&nbsp;100%测试覆盖率</p>
<p>   Urllib3功能非常强大,但是用起来却十分简单:</p>
<p>  <img src="https://images2015.cnblogs.com/blog/1032959/201612/1032959-20161208223821882-1757380167.png"></p>
<p>安装:</p>
<p>  Urllib3&nbsp;能通过pip来安装:</p>
<p>         $pip&nbsp;install&nbsp;urllib3</p>
<p>  你也可以在github上下载最新的源码,解压之后进行安装:</p>
<p>         $git&nbsp;clone&nbsp;git://github.com/shazow/urllib3.git</p>
<p>         $python&nbsp;setup.py&nbsp;install</p>
<p>urllib3的使用:</p>
<p>&nbsp;&nbsp;&nbsp;<strong>生成请求(request):</strong></p>
<p>   首先,你必须导入urllib3模块:</p>
<p>  &nbsp;&nbsp;<img src="https://images2015.cnblogs.com/blog/1032959/201612/1032959-20161208224314132-2114489173.png"></p>
<p>   然后你需要一个PoolManager实例来生成请求,由该实例对象处理与线程池的连接以及线程安全的所有细节,不需要任何人为操作:</p>
<p>&nbsp;  <img src="https://images2015.cnblogs.com/blog/1032959/201612/1032959-20161208224403554-1528296359.png"></p>
<p>   通过request()方法创建一个请求:</p>
<p>&nbsp;  <img src="https://images2015.cnblogs.com/blog/1032959/201612/1032959-20161208224431882-1642275274.png"></p>
<p>   request()方法返回一个HTTPResponse对象。</p>
<p>   你还可以通过request()方法向请求(request)中添加一些其他信息,如:</p>
<p>&nbsp;  <img src="https://images2015.cnblogs.com/blog/1032959/201612/1032959-20161208224505991-1166427746.png"></p>
<p>   请求(request)中的数据项(request&nbsp;data)可包括:</p>
<p>&nbsp;&nbsp;&nbsp;<strong>Headers:</strong></p>
<p>   在request()方法中,可以定义一个字典类型(dictionary),并作为headers参数传入:</p>
<p>&nbsp;  <img src="https://images2015.cnblogs.com/blog/1032959/201612/1032959-20161208224542960-672305702.png"></p>
<p>&nbsp;&nbsp;&nbsp;<strong>Query&nbsp;parameters:</strong></p>
<p>   对于GET、HEAD和DELETE请求,可以简单的通过定义一个字典类型作为fields参数传入即可:</p>
<p>&nbsp; &nbsp; <img src="https://images2015.cnblogs.com/blog/1032959/201612/1032959-20161208224609835-957689363.png"></p>
<p>   对于POST和PUT请求(request),需要手动对传入数据进行编码,然后加在URL之后:</p>
<p>  <img src="https://images2015.cnblogs.com/blog/1032959/201612/1032959-20161208224651726-210826905.png"></p>
<p>&nbsp;&nbsp;<strong>&nbsp;Form&nbsp;data:</strong></p>
<p>   对于PUT和POST请求(request),urllib3会自动将字典类型的field参数编码成表格类型.</p>
<p>&nbsp;&nbsp;&nbsp;<strong>JSON:</strong></p>
<p>   在发起请求时,可以通过定义body&nbsp;参数并定义headers的Content-Type参数来发送一个已经过编译的JSON数据:</p>
<p>&nbsp; <img src="https://images2015.cnblogs.com/blog/1032959/201612/1032959-20161208224728116-1311103138.png"></p>
<p>&nbsp;<strong>&nbsp; Files&nbsp;&amp;&nbsp;binary&nbsp;data:</strong></p>
<p>   使用multipart/form-data编码方式上传文件,可以使用和传入Form&nbsp;data数据一样的方法进行,并将文件定义为一个元组的形式     (file_name,file_data):</p>
<p>  <img src="https://images2015.cnblogs.com/blog/1032959/201612/1032959-20161208224848163-155048000.png"></p>
<p>   文件名(filename)的定义不是严格要求的,但是推荐使用,以使得表现得更像浏览器。同时,还可以向元组中再增加一个数据来定义文件的 MIME类型:</p>
<p>&nbsp;  <img src="https://images2015.cnblogs.com/blog/1032959/201612/1032959-20161208224945101-469176867.png"></p>
<p>   如果是发送原始二进制数据,只要将其定义为body参数即可。同时,建议对header的Content-Type参数进行</p>
<p><strong>&nbsp; &nbsp; &nbsp;stream流式响应的处理</strong></p>
<div class="cnblogs_Highlighter">
<pre class="brush:python;gutter:true;">&gt;&gt;&gt; import urllib3
&gt;&gt;&gt; http = urllib3.PoolManager()
&gt;&gt;&gt; r = http.request('GET', 'http://httpbin.org/bytes/1024', preload_content=False)
&gt;&gt;&gt; for chunk in r.stream(32):
... print(chunk)
...
&gt;&gt;&gt; r.release_conn()
注意:preload_content=False表示流式处理响应数据。

处理stream()方法读取响应数据之外,还可以使用read()方法,示例如下:

&gt;&gt;&gt; import urllib3
&gt;&gt;&gt; http = urllib3.PoolManager()
&gt;&gt;&gt; r = http.request('GET', 'http://httpbin.org/bytes/1024', preload_content=False)
&gt;&gt;&gt; r.read(4)
b'\x88\x1f\x8b\xe5'       
&gt;&gt;&gt; r.release_conn()
</pre>
</div>
<p>  </p>
<p>设置:</p>
<p>&nbsp;  <img src="https://images2015.cnblogs.com/blog/1032959/201612/1032959-20161208225043429-958299904.png"></p>
<p>&nbsp;&nbsp;<strong>&nbsp;Timeout&nbsp;:</strong></p>
<p>   使用timeout,可以控制请求的运行时间。在一些简单的应用中,可以将timeout参数设置为一个浮点数:</p>
<p>&nbsp;  <img src="https://images2015.cnblogs.com/blog/1032959/201612/1032959-20161208225110851-689186429.png"></p>
<p>   要进行更精细的控制,可以使用Timeout实例,将连接的timeout和读的timeout分开设置:</p>
<p>&nbsp;  &nbsp;&nbsp;<img src="https://images2015.cnblogs.com/blog/1032959/201612/1032959-20161208225128101-961305684.png"></p>
<p>   如果想让所有的request都遵循一个timeout,可以将timeout参数定义在PoolManager中:</p>
<p>&nbsp;   <img src="https://images2015.cnblogs.com/blog/1032959/201612/1032959-20161208225146429-73291227.png"></p>
<p>   或者</p>
<p>&nbsp;   <img src="https://images2015.cnblogs.com/blog/1032959/201612/1032959-20161208225201710-149597083.png"></p>
<p>   当在具体的request中再次定义timeout时,会覆盖PoolManager层面上的timeout。</p>
<p>&nbsp;&nbsp;&nbsp;<strong>请求重试(retrying&nbsp;requests):</strong></p>
<p>   Urllib3&nbsp;可以自动重试幂等请求,原理和handles&nbsp;redirect一样。可以通过设置retries参数对重试进行控制。Urllib3默认进行3次请求重  试,并进行3次方向改变。</p>
<p>   给retries参数定义一个整型来改变请求重试的次数:</p>
<p>&nbsp;   <img src="https://images2015.cnblogs.com/blog/1032959/201612/1032959-20161208225328757-932400839.png"></p>
<p>   关闭请求重试(retrying&nbsp;request)及重定向(redirect)只要将retries定义为False即可:</p>
<p>&nbsp;         <img src="https://images2015.cnblogs.com/blog/1032959/201612/1032959-20161208225347210-617762962.png"></p>
<p>   关闭重定向(redirect)但保持重试(retrying&nbsp;request),将redirect参数定义为False即可:</p>
<p>&nbsp;  <img src="https://images2015.cnblogs.com/blog/1032959/201612/1032959-20161208225401085-1875481488.png"></p>
<p>   要进行更精细的控制,可以使用retry实例,通过该实例可以对请求的重试进行更精细的控制。</p>
<p>   例如,进行3次请求重试,但是只进行2次重定向:</p>
<p>&nbsp;  <img src="https://images2015.cnblogs.com/blog/1032959/201612/1032959-20161208225444929-1906895636.png"></p>
<p>   如果想让所有请求都遵循一个retry策略,可以在PoolManager中定义retry参数:</p>
<p>&nbsp;  <img src="https://images2015.cnblogs.com/blog/1032959/201612/1032959-20161208225504397-944039182.png"></p>
<p>   或者</p>
<p>  &nbsp;<img src="https://images2015.cnblogs.com/blog/1032959/201612/1032959-20161208225525476-1184391582.png"></p>
<p>   当在具体的request中再次定义retry时,会覆盖 PoolManager层面上的retry。</p><br><br>
来源:https://www.cnblogs.com/lincappu/p/12801817.html
頁: [1]
查看完整版本: Python urllib3模块详解