Python Http Web服务 - URLLIB,HTTPLIB2(二、http客户端需要支持的特性)

Python Web服务

Python 3带有两个不同的库,用于与http web服务进行交互:
1. http.client
是一个实现rfc 2616(http协议)的低级库。
2. urllib.request
是建立在http.client之上的一个抽象层。它提供了访问http和ftp服务器的标准API,自动遵循http重定向,并处理一些常见的http认证形式。

那我们应该使用哪一个?
他们都不是。相反,我们应该使用httplib2,这是一个比http.client更完全实现http的开源第三方库,但比urllib.request提供了更好的抽象。


所有http客户端都应该支持五个重要功能


分别是:Caching(高速缓存),Last-modified checking(最后修改的检查),ETag checking(ETag检查),Compression(压缩,Redirect(重定向)


1.缓存

网络访问非常昂贵!

认识到任何类型的Web服务最重要的是网络访问非常昂贵。
打开连接,发送请求并从远程服务器获取响应需要很长时间。
即使在最快的宽带连接上,延迟仍然可能比我们预期的要高。
路由器行为异常,数据包丢失,中间代理受到攻击,等等。

http的设计考虑到缓存。有一整套称为缓存代理的设备,其唯一的工作就是坐在我们和世界其他地方之间,并最大限度地减少网络访问。

通过谷歌浏览器Chrome查看一个示例:
在安装chrome-extension-http-headers之后:

这里写图片描述

我们可以得到头部http头信息:

这里写图片描述


缓存加速了重复的页面浏览,并通过防止下载未更改的内容来节省大量的流量。
我们可以使用Cache-Control:max-age =来通知浏览器该组件在定义的时间内不会被改变。
这样,如果浏览器在其缓存中已经存在组件,那么我们可以避免不必要的进一步请求,因此,可以更快地执行引发缓存页面查看。

Python的http库不支持缓存,但是httplib2却支持。


2.最后修改检查

有些数据永远不会改变,而其他数据总是变化的。请求数据时,服务器上的数据可能会发生了变化。
http也有这个解决方案。当我们第一次请求数据时,服务器可以发回一个Last-Modified头。这正是它听起来像:数据被更改的日期。
当我们在第二次(或第三次或第四次)请求相同的数据时,我们可以发送一个If-Modified-Since头部与我们的请求,以及我们上一次从服务器返回的日期。如果自那时起数据发生了变化,那么服务器会给我们提供200个状态码的新数据。但是如果从那时起数据没有改变,服务器就会发回一个特殊的http 304状态码,这意味着这个数据从上次我们要求的时候起并没有改变。

我们可以在命令行上使用cURL来测试它:

$ curl -I -H"If-Modified-Since:Sun,20 Jan 2013 19:56:58 GMT" 
 http://www.bogotobogo.com/python/images/python_http_web_services/Browsers.png

##响应:
HTTP/1.1 304 Not Modified
Date: Sun, 20 Jan 2013 23:21:23 GMT
Server: Apache
ETag: "664002c-2f09-4d3bdbf48a672"
Vary: Accept-Encoding

这是一个改进,因为当服务器发送304时,它不会重新发送数据。
我们所得到的是状态码。即使在我们的缓存副本已经过期之后,最后修改的检查也确保了如果没有改变,我们将不会下载相同的数据两次。
(事实上,这304响应同样也包含了缓存头。代理服务器会保留数据的副本,它甚至正式后到期,同时希望在数据没有真正改变下一请求回应一个304个状态码,并更新缓存信息。 )

Python的http库不支持上次修改的日期检查,但是httplib2却支持


3. ETag检查

一个ETag或entity标签,是HTTP,对万维网的协议的一部分。这是HTTP为Web缓存验证提供的几种机制之一,它允许客户端发出条件请求。这使得缓存效率更高,节省带宽,因为如果内容没有改变,Web服务器不需要发送完整的响应。

使用ETag,服务器会在ETag头部发送一个哈希码以及我们请求的数据。

200 OK
Date: Mon, 21 Jan 2013 00:07:51 GMT
Content-Encoding: gzip
Last-Modified: Sun, 20 Jan 2013 19:56:58 GMT
Server: Apache
ETag: "664002c-2f09-4d3bdbf48a672"
Vary: Accept-Encoding
Content-Type: image/png
Accept-Ranges: bytes
Content-Length: 12054

我们请求相同的数据时,如果数据没有改变,服务器将会发回一个304状态码。
与上次修改日期检查一样,服务器只发送304状态码; 它不会再次向我们发送相同的数据。
通过在我们的第二个请求中包含ETag hash,我们告诉服务器,如果它仍然匹配这个hash,就不需要重新发送相同的数据,因为我们仍然有来自上次的数据。

$ curl -I -H "If-None-Match: \"664002c-2f09-4d3bdbf48a672\""
 http://www.bogotobogo.com/python/images/python_http_web_services/Browsers.png

##响应
HTTP/1.1 304 Not Modified
Date: Mon, 21 Jan 2013 00:14:50 GMT
Server: Apache
ETag: "664002c-2f09-4d3bdbf48a672"
Vary: Accept-Encoding

请注意,ETag通常用引号”“引起来,但引号是值的一部分。
这意味着我们需要在If-None-Match标题中将引号发送回服务器。

Python的http库不支持Etag,但是httplib2支持


4.压缩

当我们谈论HTTP Web服务时,我们几乎总是在谈论通过线路来回传输基于文本的数据。
它可以是xml,json,也可以是纯文本。
无论格式如何,对内容压缩都是个很好方案

http支持几种压缩算法。两种最常见的类型是gzip和deflate。当我们通过http请求一个资源时,我们可以要求服务器以压缩格式发送它。我们在请求中包含一个Accept-Encoding头,它列出了我们支持的压缩算法。如果服务器支持任何相同的算法,它会发送给我们压缩的数据(使用内容编码头来告诉我们使用哪种算法)。然后,我们来解压缩数据。

这里写图片描述

Python的http库不支持压缩,但httplib2支持。


5.重定向

网站正在不断变化。即使Web服务可以重组,甚至域可能会移动。每次我们从http服务器请求任何资源时,服务器都会在其响应中包含一个状态码:

1.  200:一切正常
2.  404页面不存在
3.  300:重定向

http有几种不同的表示资源已经移动的方式。
两种最常见的技术是状态码302和301。
1. 302:临时重定向; 它意味着oops,暂时移到这里,然后在Location标题中给出临时地址。
如果我们得到一个302状态码和一个新地址,http规范说我们应该使用新的地址来得到我们所要求的,但是下一次我们要访问同一个资源时,我们应该重试旧的地址。

2. 301:永久重定向; 这意味着额,永久移动,然后在地址标题中给出新的地址。
如果我们得到一个301状态码和一个新的地址,那么我们应该使用新的地址。
当urllib.request模块从http服务器收到相应的状态码时,会自动遵循重定向,但是并没有告诉我们这样做。我们最终会得到我们要求的数据,但是我们永远不会知道底层的库有助于我们进行重定向。
所以我们将继续敲击旧地址,每次我们将重定向到新地址,并且每次urllib.request模块都将有助于重定向。换句话说,它将永久重定向视为临时重定向。这意味着两次往返而不是一次,这对服务器不利,对我们不利。

httplib2为我们处理永久重定向。它不仅会告诉我们发生了永久重定向,它会在本地跟踪它们,并在请求它们之前自动重写重定向的URL。


原文地址:

http://www.bogotobogo.com/python/python_http_web_services.php
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值