urllib2中的两个重要概念:Openers和Handlers
Openers
我们都知道urlopen函数,这就是urllib2默认的opener,所以说我们通常都是使用一个opener来获取url,但是你可以根据自己的需要去构建自己的特有的opener。
如果你希望用特定处理器获取URLs你会想创建一个openers,例如获取一个能处理cookie的opener,或者获取一个不重定向的opener。
创建一个opener的方法如下:
1、要创建一个 opener,可以实例化一个OpenerDirector,然后调用.add_handler(some_handler_instance)。
2、同样,可以使用build_opener,这是一个更加方便的函数,用来创建opener对象,他只需要一次函数调用。build_opener默认添加几个处理器,但提供快捷的方法来添加或更新默认处理器。其他的处理器handlers你或许会希望处理代理,验证,和其他常用但有点特殊的情况。
3、install_opener 用来创建(全局)默认opener。这个表示调用urlopen将使用你安装的opener。 Opener对象有一个open方法,该方法可以像urlopen函数那样直接用来获取urls:通常不必调用install_opener,除了为了方便。
Handlers
urllib2提供了很多handler,开发人员还可以按照一定的规范制定自定义的handler。下面介绍一下部分已有的handler:
- BaseHandler 所有 handler 都必须继承这个。
- HTTPErrorProcessor HTTP 错误处理,内部有一个方法。
- HTTPDefaultErrorHandler 万能的,不想理会的错误就用它。
- HTTPRedirectHandler 重定向处理,状态码是 30X 的时候会用到。
- ProxyHandler 如果开了代理,会用到这个 handler。
- HTTPPasswordMgr 秘密管理器,它里面会根据不同的连接,不同的 realm 管理密码。
- AbstractBasicAuthHandler HTTP 认证抽象类。
- HTTPBasicAuthHandler 继承自 AbstractBasicAuthHandler 类,HTTP 基本认证。
- AbstractBasicAuthHandler 继承自 AbstractBasicAuthHandler 类;如果开了代理,需要用这个认证类。
- AbstractHTTPHandler HTTP 处理抽象类,其实不抽象了;它内部有一个 do_open() 方法,是 HTTP 连接的核心,它返回上一节提到过的 addinfourl 对象,动作也和上一节提到的 open_http() 大同小异。
- HTTPHandler 这个类里有个 http_open() 方法,它会被安置在 OpenerDirector 对象的 handle_open list 中,很明显它是管理 HTTP 连接的,发送或者接受数据,其内部调用上面提到的 do_open() 方法。
- HTTPSHandler HTTPS
- HTTPCookieProcessor 里面有 http_request 和 http_response 方法,分别是 cookies 的预处理和善后处理,用作设置和提取 cookies
- UnknownHandler 里面定义了 unknown_open 方法;当遇到无法理解的 url 时候,就会被调用
- FileHandler 处理本地文件或者 ftp,这要视被传入的 url 而定
- FTPHandler 封装了 ftp 的处理,会创建上一节提到的 ftpwrapper。
- CacheFTPHandler 带缓存的 FTPHandler,里面主要记录最近 ftp 连接的信息(实际上是 ftpwrapper 对象),并各自设置了过期时间。
下面简单介绍一个基本的用户验证的例子,更好的理解一下opener和handler的使用。
我们将用到HTTPBasicAuthHandler的实例,并让opener使用这个handler,HTTPBasicAuthHandler使用一个密码管理的对象(HTTPPasswordMgr)来处理URLs和realms来映射用户名和密码。
如果你知道realm(从服务器发送来的头里)是什么,你就能使用HTTPPasswordMgr。通常人们不关心realm是什么。那样的话,就能用方便的HTTPPasswordMgrWithDefaultRealm。
这个将在你为URL指定一个默认的用户名和密码。这将在你为特定realm提供一个其他组合时得到提供。我们通过给realm参数指定None提供给add_password来指示这种情况。【^_^】
# -*- coding: utf-8 -*-
import urllib2
# 创建一个密码管理者
password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
# 添加用户名和密码
top_level_url = "http://example.com/foo/"
# 如果知道 realm, 我们可以使用他代替 ``None``.
# password_mgr.add_password(None, top_level_url, username, password)
password_mgr.add_password(None, top_level_url,'why', '1223')
# 创建了一个新的handler
handler = urllib2.HTTPBasicAuthHandler(password_mgr)
# 创建 "opener" (OpenerDirector 实例)
opener = urllib2.build_opener(handler)
a_url = 'http://www.baidu.com/'
# 使用 opener 获取一个URL
opener.open(a_url)
# 安装 opener.
# 现在所有调用 urllib2.urlopen 将用我们的 opener.
urllib2.install_opener(opener)
真正的含义我也还在不断了解当中,希望可以继续加深对urllib2和HTTP的认识!
参考:
urllib2小剖 :http://daoluan.net/blog/urllib2-source-decode/
[Python]网络爬虫(四):Opener与Handler的介绍和实例应用 :http://blog.csdn.net/pleasecallmewhy/article/details/8924889