转自:http://www.cnblogs.com/kennyhr/p/4018668.html(侵权可联系本人删掉)
一直以来技术群里会有新入行的同学提问关于urllib和urllib2以及cookielib相关的问题。所以我打算在这里总结一下,避免大家反复回答同样的问题浪费资源。
这篇属于教程类的文字,如果你已经非常了解urllib2和cookielib那么请忽略本篇。
首先从一段代码开始,
#cookie
import urllib2
import cookielib
cookie = cookielib.CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie))
request = urllib2.Request(url='http://www.baidu.com/')
request.add_header('User-Agent','Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1')
response = opener.open(request)
for item in cookie:
print item.value
很多同学说,我可以直接在openr.open()里写url,为什么你要用request。其实我这么写就是为了整理一下一般使用urllib2构造请求的常用步骤。
初步,urllib2构造请求常用步骤(结合上面的代码):
1、handler
handler既urllib2.build_opener(handler)中传递的对象参数,以下是官方的常用handler
urllib2.HTTPHandler() 通过HTTP打开URL
urllib2.CacheFTPHandler() 具有持久FTP连接的FTP处理程序
urllib2.FileHandler() 打开本地文件
urllib2.FTPHandler() 通过FTP打开URL
urllib2.HTTPBasicAuthHandler() 通过HTTP验证处理
urllib2.HTTPCookieProcessor() 处理HTTP cookie
urllib2.HTTPDefaultErrorHandler() 通过引发HTTPError异常处理HTTP错误
urllib2.HTTPDigestAuthHandler() HTTP摘要验证处理
urllib2.HTTPRedirectHandler() 处理HTTP重定向
urllib2.HTTPSHandler() 通过安全HTTP重定向
urllib2.ProxyHandler() 通过代理重定向请求
urllib2.ProxyBasicAuthHandler 基本的代理验证
urllib2.ProxyDigestAuthHandler 摘要代理验证
urllib2.UnknownHandler 处理所有未知URL的处理程序
2、request
request=urllib2.Request(url='')
request.add_data(data) 如果请求是HTTP,则方法改为POST。注意该方法不会将data追加到之前已经设置的任何数据上,而是使用现在的data替换之前的
request.add_header(key,val) key是报头名,val是包头值,两个参数都是字符串
request.add_unredirected_header(key,val) 同上,但是不会添加到重定向请求中
request.set_proxy(host,type) 准备请求到服务器。使用host替换原来的主机,使用type替换原来的请求类型
3、opener
基本的urlopen()函数不支持验证、cookie或其他的HTTP高级功能。要支持这些功能,必须使用build_opener()函数来创建自己的自定义Opener对象
建自己的自定义Opener对象,通常有两种方式:
a)
opener=urllib2.OpenerDirector()
opener.add_handler(handler)
b)
opener=urllib2.OpenerDirector()
urllib2.build_opener(handler)
install_opener(opener)
安装opener作为urlopen()使用的全局URL opener,即意味着以后调用urlopen()时都会使用安装的opener对象。opener通常是build_opener()创建的opener对象。
4、content_stream
content_stream=opener.open(request)
5、content_stream.read()
通过以上5个步骤,你就可以得到和本篇开始处code差不多的代码。这样你就完成了一个urllib2基本使用方式的构造。你也可以将以上5个步骤封装成类,但是我自己觉得并不是非常简介。
urllib2模块不仅可以使用urlopen()函数还可以自定义opener来访问网页
但同时要注意:urlretrieve()函数是urllib模块中的,urllib2模块中不存在该函数。但是使用urllib2模块时一般都离不开urllib模块,因为post的数据需要使用urllib.urlencode()函数来编码
进阶,urllib2更多使用细节:
1、Proxy的设置
import urllib2
enable_proxy=True
proxy_handler=urllib2.ProxyHandler({'http':'http://some-proxy.com:8080'})
null_proxy_handler = urllib2.ProxyHandler({})
if enable_proxy:
opener = urllib2.build_opener(proxy_handler)
else:
opener = urllib2.build_opener(null_proxy_handler)
urllib2.install_opener(opener)
ps:使用urllib2.install_opener()会设置urllib2的全局opener。这样后面的使用会很方便,但不能做更细致的控制,如果想在程序中使用两个不同的proxy设置等。比较好的方法就是不适用install_opener去更改全局的设置,而只是直接调用opener的open方法代替全局的urlopen方法。
2、timeout设置
# < py2.6
import urllib2
import socket
socket.setdefaulttimeoust(10) #one way
urllib2.socket.setdefaulttimeout(10)#anther way
# >=py2.6
import urllib2
response = urllib2.urlopen('http://www.google.com',timeout=10)
3、在http request中加入特定的header
要加入header,需要使用Request对象:
import urllib2
request = urllib2.Request(url)
request.add_header('User-Agent','fake-client')
response = urllib2.urlopen(request)
对有些header要特别留意,服务器会针对这些header做检查:
User-Agent:有些服务器或Proxy会通过该值来判断是否是浏览器发出的请求
Content-Type:在使用REST接口时,服务器会检查该值,用来确定HTTP Body中的内容该怎样解析。常见的取值有:
application/xml在XML RPC,如RESTful/SOAP调用时使用
application/json在JSON RPC调用时使用
application/x-www-form-urlencoded浏览器提交web表单时使用
4、Redirect
urllib2默认情况下会针对HTTP 3xx返回码自动进行redirect动作,无需人工配置。要检测是否发生了redirect动作,只要检查一下Response的URL和Request的URL是否一直就可以了。
import urllib2
response = urllib2.urlopen('http://www.g.cn')
redirected = response.geturl() == 'http://www.google.cn'
如果不想自动redirect,除了使用更地层的httplib库意外,还可以自定义HTTPRedirectHandler类。
import urllib2
class RedirectHandler(urllib2.HTTPRedirectHandler):
def http_error_301(self,req,fp,code,msg,headers):
pass
def http_error_302(self,req,fp,code,msg,headers):
pass
opener = urllib2.build_opener(RedirectHandler)
opener.open('http://www.google.cn')
5、cookie
urllib2对cookie的处理也是自动的。如果需要得到某个cookie的值,如下
import urllib2
import cookielib
cookie = cookielib.CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie))
response = opener.open('http://www.google.cn')
for item in cookie:
print item.value
6、使用HTTP的PUT和DELETE方法
urllib2只支持HTTP的GET和POST方法,如果要使用HTTP PUT和DELETE,只能使用比较低层的httplib库。
import urllib2
request = urllib2.Request(url,data=data)
request.get_method=lambda:'PUT'#or 'DELETE'
response = urllib2.urlopen(request)
7、得到HTTP的返回码
对于200OK来说,只要使用urlopen返回的response对象的getcode()方法就可以得到HTTP的返回码。对其他返回码来说,urlopen会抛出异常。这时候,就要检查异常对象的code了
import urllib2
try:
response = urllib2.urlopen('http://www.google.cn')
except urllib2.HTTPError, e:
print e.code
8、debug log
使用urllib2时,可以通过下面的方法把debug log打开,这样收发包的内容就会在屏幕上打印出了
import urllib2
httpHandler=urllib2.HTTPHandler(debuglevel=1)
httpsHandler = urllib2.HTTPSHandler(debuglevel=1)
opener = urllib2.build_opener(httpHandler, httpsHandler)
urllib2.install_opener(opener)
response = urllib2.urlopen('http://www.google.cn')