ITEEDU

OpenerDirector类

当你获取一个URL时,你使用一个opener(OpenerDirector)。正常情况下我们一直使用默认的opener,通过urlopen,但你也可以创建自定义的openers。

opener使用handler处理任务,所有的重活都交给这些handlers来做。每一个handler知道怎么以特定的url协议打开url,或者怎么处理打开url的某些方面,如,HTTP重定向,或者HTTP cookie。

你可以用build_opener,这是一个很方便的创建opener对象的函数,它只有一个函数调用。

install_opener能设置一个全局opener对象,这意味着调用urlopen将会都用你刚安装的opener。

opener对象有一个open方法,它可以以一种和urlopen函数同样的方式直接调用来获取url:除非是为了方便,没有必要调用install_opener。

OpenerDirector操作类是一个管理很多处理类(Handler)的类。而所有这些 Handler 类都对应处理相应的协议,或者特殊功能。

分别有下面的处理类:BaseHandler,HTTPErrorProcessor,HTTPDefaultErrorHandler,HTTPRedirectHandler,ProxyHandler,
AbstractBasicAuthHandler,HTTPBasicAuthHandler,ProxyBasicAuthHandler,AbstractDigestAuthHandler,
ProxyDigestAuthHandler,AbstractHTTPHandler,HTTPHandler,HTTPCookieProcessor,UnknownHandler,
FileHandler,FTPHandler,CacheFTPHandler

们都是遵循相应的规则,需求创建的类,甚至是相似的。你基本的需是http协议的处理类。

最简单的urlib2的使用,也就是源码中给出的使用方式:

#file: urllib2.py
_opener=None
def urlopen(url, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
	global _opener
	if _opener is None:
		_opener=build_opener()
	return _opener.open(url, data, timeout)

对比urllib.urlopen()

现在分析urllib2里的urlopen, 一般我们直接调用urlopen()就是表示去调用build_opener()方法,这里_opener 是一个全局变量。第一次使用时,通过build_opener() 得到一个值,以后再次使用就是保存到这个全局变量中值。 然后用build_opener()方法返回的类对象去调用该对象的open方法。bulid_opener()创建自己的opener对象

使用urllib2.urlopen()生成的是我们前面提到的管理很多处理器类的OpenerDirector操作类,然后给他加入很多的处理器,作为其一个属性,然后调用该处理器操作类对象的open方法就可以获取页面了。 流程就是

  1. 生成一个处理器opener = OpenerDirector()对象
  2. 给这个处理器对象加入处理器opener.add_handler(h)
  3. 使用打开方法,可能是具体handler类的打开方法。获取至本地的“文件流”对象,使用“文件流”。read()获取内容,写入文件

即只要你是使用urllib2,不管你是要用代理,还是要用ftp,http,都逃不过这套过程。