[Python]网络爬虫(四):Opener与Handler

在开始后面的内容之前,先来解释一下urllib2中的两个个方法:info and geturl 

urlopen返回的应答对象response(或者HTTPError实例)有两个很有用的方法info()和geturl()

1.geturl():

geturl()返回获取的真实的URL,这个很有用,因为urlopen(或者opener对象使用的)或许会有重定向。获取的URL或许跟请求URL不同。

以人人中的一个超级链接为例,

我们建一个urllib2_test10.py来比较一下原始URL和重定向的链接

[python] view plaincopy
  1. from urllib2 import Request, urlopen, URLError, HTTPError  
  2.   
  3.   
  4. old_url = 'http://rrurl.cn/b1UZuP'  
  5. req = Request(old_url)  
  6. response = urlopen(req)    
  7. print 'Old url :' + old_url  
  8. print 'Real url :' + response.geturl()  
运行之后可以看到真正的链接指向的网址:



2.info():

info()返回对象的字典对象,该字典描述了获取的页面情况。通常是服务器发送的特定头headers。

经典的headers包含"Content-length","Content-type",和其他内容。

我们建一个urllib2_test11.py来测试一下info的应用:

[python] view plaincopy
  1. from urllib2 import Request, urlopen, URLError, HTTPError  
  2.   
  3. old_url = 'http://www.baidu.com'  
  4. req = Request(old_url)  
  5. response = urlopen(req)    
  6. print 'Info():'  
  7. print response.info()  
运行的结果如下,可以看到页面的相关信息:

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

一、opener

       urllib2.urlopen()函数不支持验证、cookie或者其它HTTP高级功能。要支持这些功能,必须使用build_opener()(可以用于让python程序模拟浏览器进行访问,作用你懂得~)函数创建自定义Opener对象。

       用法如下

build_opener([handler1 [ handler2, ... ]])
      参数handler是Handler实例,常用的有HTTPBasicAuthHandler、HTTPCookieProcessor、ProxyHandler等。
      build_opener ()返回的对象具有open()方法,与urlopen()函数的功能相同。
      如果要修改http报头,可以用:

import urllib2
opener = urllib2.build_opener()
opener.addheaders = [('User-agent', 'Mozilla/5.0')]
opener.open('http://www.example.com/')

install_opener(opener)

安装不同的opener对象作为urlopen()使用的全局opener。

密码验证(HTTPBasicAuthHandler)

HTTPBasicAuthHandler()处理程序可用add_password()来设置密码。

h.add_password(realm,uri,user,passwd)
realm是与验证相关联的名称或描述信息,取决于远程服务器。uri是基URL。user和passwd分别指定用户名和密码。
import urllib2
auth=urllib2.HTTPBasicAuthHandler()
auth.add_password('Administrator','http://www.example.com','Dave','123456')
opener=urllib2.build_opener(auth)
u=opener.open('http://www.example.com/evilplan.html')

Cookie处理(HTTPCookieProcessor)

import urllib2,cookielib
cookie=cookielib.CookieJar()
cookiehand=urllib2.HTTPCookieProcessor(cookie)
opener=urllib2.build_opener(cookiehand)

代理(ProxyHandler)

ProxyHandler(proxies)参数proxies是一个字典,将协议名称(http,ftp)等映射到相应代理服务器的URL。

proxy=ProxyHandler({'http':'http://someproxy.com:8080'})
auth=HTTPBasicAuthHandler()
auth.add_password()
opener=build_opener(auth,proxy)
也可以在urlopen中使用代理
import urllib2  
proxy = 'http://%s:%s@%s' % ('userName', 'password', 'proxy')  
inforMation = urllib2.urlopen("http://www.example.com", proxies={'http':proxy})  

二、Handler

handler用于处理URL,例如HTTP重定向、HTTP cookies等。
如果你希望创建一个特定的openers,例如获取一个能处理cookie的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。


代码如下:

[python] view plaincopy
  1. # -*- coding: utf-8 -*-  
  2. import urllib2  
  3.   
  4. # 创建一个密码管理
  5. password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm()  
  6. # 添加用户名和密码  
  7.   
  8. top_level_url = "http://example.com/foo/"   
  9. password_mgr.add_password(None, top_level_url,'why''1223')  
  10.   
  11. # 创建了一个新的handler  
  12. handler = urllib2.HTTPBasicAuthHandler(password_mgr)  
  13.   
  14. # 创建 "opener" (OpenerDirector 实例)  
  15. opener = urllib2.build_opener(handler)  
  16.   
  17. a_url = 'http://www.baidu.com/'  
  18.   
  19. # 使用 opener 获取一个URL  
  20. opener.open(a_url)  
  21.   
  22. # 安装 opener.  
  23. # 现在所有调用 urllib2.urlopen 将用我们的 opener.  
  24. urllib2.install_opener(opener)  
  25.   
  26.    

注意:除了HHTPBasicAuthHandler以外,ProxyHandler,UnknownHandler,HTTPHandler,HTTPDefaultErrorHandler, HTTPRedirectHandler,FTPHandler, FileHandler, HTTPErrorProcessor均会返回Handler




欢迎收听我的微信公众号




你可能感兴趣的:(Python)