|
11.6. 处理 Last-Modified 和 ETag
既然你知道如何在你的 web 服务请求中添加自定义的 HTTP 头信息, 接下来看看添加 Last-Modified 和 ETag 头信息的支持。
下面的这些例子将以调试标记置为关闭的状态来显示输出结果。 如果你还停留在上一部分的开启状态, 可以使用 httplib.HTTPConnection.debuglevel = 0 将其设置为关闭状态。 或者, 如果你认为有帮助也可以保持为开启状态。
例 11.6. 测试 Last-Modified
>>> import urllib2
>>> request = urllib2.Request('http://diveintomark.org/xml/atom.xml')
>>> opener = urllib2.build_opener()
>>> firstdatastream = opener.open(request)
>>> firstdatastream.headers.dict
{'date': 'Thu, 15 Apr 2004 20:42:41 GMT',
'server': 'Apache/2.0.49 (Debian GNU/Linux)',
'content-type': 'application/atom+xml',
'last-modified': 'Thu, 15 Apr 2004 19:45:21 GMT',
'etag': '"e842a-3e53-55d97640"',
'content-length': '15955',
'accept-ranges': 'bytes',
'connection': 'close'}
>>> request.add_header('If-Modified-Since',
... firstdatastream.headers.get('Last-Modified'))
>>> seconddatastream = opener.open(request)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "c:\python23\lib\urllib2.py", line 326, in open
'_open', req)
File "c:\python23\lib\urllib2.py", line 306, in _call_chain
result = func(*args)
File "c:\python23\lib\urllib2.py", line 901, in http_open
return self.do_open(httplib.HTTP, req)
File "c:\python23\lib\urllib2.py", line 895, in do_open
return self.parent.error('http', req, fp, code, msg, hdrs)
File "c:\python23\lib\urllib2.py", line 352, in error
return self._call_chain(*args)
File "c:\python23\lib\urllib2.py", line 306, in _call_chain
result = func(*args)
File "c:\python23\lib\urllib2.py", line 412, in http_error_default
raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
urllib2.HTTPError: HTTP Error 304: Not Modified
还记得当调试标记设置为开启时所有那些你看到的 HTTP 头信息打印输出吗? 这里便是你如何以编程方式访问它们: firstdatastream.headers 是 一个类似 dictionary 行为的对象 并且 允许你获得任何个别的从 HTTP 服务器返回的头信息。
在第二次请求时, 你用第一次请求获得的最近修改时间添加了 If-Modified-Since 头信息。 如果数据没被改变, 服务器应该返回一个 304 状态代码。
毫无疑问, 数据没被改变。 你可以从跟踪返回结果看到 urllib2 扔掉了特殊异常, HTTPError, 响应中的 304 状态代码。 这有点不寻常, 并且完全没有任何帮助。 毕竟, 它不是个错误; 你明确地询问服务器如果没有变化就不要发送任何数据, 并且数据没有变化, 所以服务器告诉你它没有为你发送任何数据。 那不是个错误; 实际上也正是你所期望的。
urllib2 也为你认为是错误的其他条件引发 HTTPError 异常, 比如 404 (page not found)。 实际上, 它将为 任何 除了状态代码 200 (OK), 301 (permanent redirect), 或 302 (temporary redirect) 之外的状态引发 HTTPError。 当你企图捕获状态代码并简单返回它, 不抛弃任何异常时, 这应该对你很有帮助。 为了实现它, 你将需要自定义一个 URL 头信息。 |
|