零基础写python爬虫之urllib2中的两个重要概念:Openers和Handlers


Posted in Python onNovember 05, 2014

在开始后面的内容之前,先来解释一下urllib2中的两个个方法:info / geturl
urlopen返回的应答对象response(或者HTTPError实例)有两个很有用的方法info()和geturl()

1.geturl():

这个返回获取的真实的URL,这个很有用,因为urlopen(或者opener对象使用的)或许会有重定向。获取的URL或许跟请求URL不同。
以人人中的一个超级链接为例,
我们建一个urllib2_test10.py来比较一下原始URL和重定向的链接:

from urllib2 import Request, urlopen, URLError, HTTPError  

old_url = 'http://rrurl.cn/b1UZuP'  

req = Request(old_url)  

response = urlopen(req)    

print 'Old url :' + old_url  

print 'Real url :' + response.geturl() 

运行之后可以看到真正的链接指向的网址:

零基础写python爬虫之urllib2中的两个重要概念:Openers和Handlers

2.info():

这个返回对象的字典对象,该字典描述了获取的页面情况。通常是服务器发送的特定头headers。目前是httplib.HTTPMessage 实例。
经典的headers包含"Content-length","Content-type",和其他内容。
我们建一个urllib2_test11.py来测试一下info的应用:

from urllib2 import Request, urlopen, URLError, HTTPError  

old_url = 'http://www.baidu.com'  

req = Request(old_url)  

response = urlopen(req)    

print 'Info():'  

print response.info() 

运行的结果如下,可以看到页面的相关信息:

零基础写python爬虫之urllib2中的两个重要概念:Openers和Handlers

下面来说一说urllib2中的两个重要概念:Openers和Handlers。

1.Openers:

当你获取一个URL你使用一个opener(一个urllib2.OpenerDirector的实例)。
正常情况下,我们使用默认opener:通过urlopen。
但你能够创建个性的openers。

2.Handles:

Openers使用处理器handlers,所有的“繁重”工作由handlers处理。
每个handlers知道如何通过特定协议打开URLs,或者如何处理URL打开时的各个方面。
例如HTTP重定向或者HTTP cookies。

如果你希望用特定处理器获取URLs你会想创建一个openers,例如获取一个能处理cookie的opener,或者获取一个不重定向的opener。

要创建一个 opener,可以实例化一个OpenerDirector,
然后调用.add_handler(some_handler_instance)。
同样,可以使用build_opener,这是一个更加方便的函数,用来创建opener对象,他只需要一次函数调用。
build_opener默认添加几个处理器,但提供快捷的方法来添加或更新默认处理器。
其他的处理器handlers你或许会希望处理代理,验证,和其他常用但有点特殊的情况。

install_opener 用来创建(全局)默认opener。这个表示调用urlopen将使用你安装的opener。
Opener对象有一个open方法。
该方法可以像urlopen函数那样直接用来获取urls:通常不必调用install_opener,除了为了方便。

说完了上面两个内容,下面我们来看一下基本认证的内容,这里会用到上面提及的Opener和Handler。

Basic Authentication 基本验证

为了展示创建和安装一个handler,我们将使用HTTPBasicAuthHandler。
当需要基础验证时,服务器发送一个header(401错误码) 请求验证。这个指定了scheme 和一个‘realm',看起来像这样:Www-authenticate: SCHEME realm="REALM".
例如
Www-authenticate: Basic realm="cPanel Users"
客户端必须使用新的请求,并在请求头里包含正确的姓名和密码。
这是“基础验证”,为了简化这个过程,我们可以创建一个HTTPBasicAuthHandler的实例,并让opener使用这个handler就可以啦。

HTTPBasicAuthHandler使用一个密码管理的对象来处理URLs和realms来映射用户名和密码。
如果你知道realm(从服务器发送来的头里)是什么,你就能使用HTTPPasswordMgr。

通常人们不关心realm是什么。那样的话,就能用方便的HTTPPasswordMgrWithDefaultRealm。
这个将在你为URL指定一个默认的用户名和密码。
这将在你为特定realm提供一个其他组合时得到提供。
我们通过给realm参数指定None提供给add_password来指示这种情况。

最高层次的URL是第一个要求验证的URL。你传给.add_password()更深层次的URLs将同样合适。
说了这么多废话,下面来用一个例子演示一下上面说到的内容。
我们建一个urllib2_test12.py来测试一下info的应用:

# -*- 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) 

  
注意:以上的例子我们仅仅提供我们的HHTPBasicAuthHandler给build_opener。
默认的openers有正常状况的handlers:ProxyHandler,UnknownHandler,HTTPHandler,HTTPDefaultErrorHandler, HTTPRedirectHandler,FTPHandler, FileHandler, HTTPErrorProcessor。
代码中的top_level_url 实际上可以是完整URL(包含"http:",以及主机名及可选的端口号)。
例如:http://example.com/。
也可以是一个“authority”(即主机名和可选的包含端口号)。
例如:“example.com” or “example.com:8080”。
后者包含了端口号。
Python 相关文章推荐
Python实现的数据结构与算法之链表详解
Apr 22 Python
利用python实现数据分析
Jan 11 Python
Python模拟用户登录验证
Sep 11 Python
Python 多进程并发操作中进程池Pool的实例
Nov 01 Python
python SSH模块登录,远程机执行shell命令实例解析
Jan 12 Python
python实现简单登陆流程的方法
Apr 22 Python
python opencv pytesseract 验证码识别的实现
Aug 28 Python
python批量修改文件名的示例
Sep 27 Python
一文搞懂如何实现Go 超时控制
Mar 30 Python
python实战之用emoji表情生成文字
May 08 Python
python编程实现清理微信重复缓存文件
Nov 01 Python
再谈python_tkinter弹出对话框创建
Mar 20 Python
零基础写python爬虫之HTTP异常处理
Nov 05 #Python
零基础写python爬虫之使用urllib2组件抓取网页内容
Nov 04 #Python
零基础写python爬虫之爬虫的定义及URL构成
Nov 04 #Python
使用Python编写简单网络爬虫抓取视频下载资源
Nov 04 #Python
Python爬取Coursera课程资源的详细过程
Nov 04 #Python
使用python开发vim插件及心得分享
Nov 04 #Python
Python学习笔记之os模块使用总结
Nov 03 #Python
You might like
php创建多级目录代码
2008/06/05 PHP
smarty模板中拼接字符串的方法
2014/02/14 PHP
PHP+memcache实现消息队列案例分享
2014/05/21 PHP
php数组使用规则分析
2015/02/27 PHP
laravel 多图上传及图片的存储例子
2019/10/14 PHP
jQuery创建插件的代码分析
2011/04/14 Javascript
Jquery getJSON方法详细分析
2013/12/26 Javascript
结合JQ1.9通过js正则判断各种浏览器版本的方法
2013/12/30 Javascript
Javascript加载速度慢的解决方案
2014/03/11 Javascript
js库Modernizr的介绍和使用
2015/05/07 Javascript
使用AngularJS和PHP的Laravel实现单页评论的方法
2015/06/19 Javascript
JavaScript知识点总结(十六)之Javascript闭包(Closure)代码详解
2016/05/31 Javascript
有趣的bootstrap走动进度条
2016/12/01 Javascript
Vue.js组件tabs实现选项卡切换效果
2016/12/01 Javascript
TypeScript入门-接口
2017/03/30 Javascript
详解vue.js 开发环境搭建最简单攻略
2017/06/12 Javascript
js移动端事件基础及常用事件库详解
2017/08/15 Javascript
ElementUI 修改默认样式的几种办法(小结)
2020/07/29 Javascript
python随机生成指定长度密码的方法
2015/04/04 Python
Python使用tablib生成excel文件的简单实现方法
2016/03/16 Python
从头学Python之编写可执行的.py文件
2017/11/28 Python
Django rest framework基本介绍与代码示例
2018/01/26 Python
pandas.DataFrame删除/选取含有特定数值的行或列实例
2018/11/07 Python
Python实现网站表单提交和模板
2019/01/15 Python
使用matlab或python将txt文件转为excel表格
2019/11/01 Python
Pytorch DataLoader 变长数据处理方式
2020/01/08 Python
使用pytorch完成kaggle猫狗图像识别方式
2020/01/10 Python
One.com挪威:北欧成长最快的网络托管公司
2016/11/19 全球购物
Baby Tulai澳大利亚:美国婴儿背带品牌
2018/10/15 全球购物
美国购买肉、鸭、家禽、鹅肝和熟食网站:D’Artagnan
2018/11/13 全球购物
Bose美国官网:购买Bose耳机和音箱
2019/03/10 全球购物
T3官网:头发造型工具
2019/12/26 全球购物
"引用"与多态的关系
2013/02/01 面试题
商务助理岗位职责
2013/11/13 职场文书
2015年创先争优活动总结
2015/03/27 职场文书
幼儿园端午节活动总结
2015/05/05 职场文书