urllib2是Python的一个获取URLs的组件。他以urlopen函数的形式提供了一个非常简单的接口,具有利用不同协议获取URLs的能力,同样提供了一个比较复杂的接口来处理一般情况。
urllib2支持获取不同格式的URLs例如:ftp、Gopher等,并利用它们相关网络协议进行获取。
urllib2可用来完成以下功能:
1.获取Web页面
2.在远程http服务器上验证
3.额外数据请求,如表单提交(GET和POST)
4.异常处理
5.非http协议通信(如FTP)
1.获取Web页面
例1:打印html页面,下面是最简单的形式
-
12345
#!/usr/bin/env python
import
urllib2
response
=
urllib2.urlopen(
'http://www.google.com'
)
html
=
response.read()
print
html
例2:打开指定页面并打印html页面和一些额外的信息,采用了urllib2最一般的形式:i、urllib2.Request()的功能是构造一个请求信息,返回的req就是一个构造好的请求。ii、urllib2.urlopen()的功能是发送刚刚构造好的请求req,并返回一个文件类的对象response,包括了所有的返回信息。iii、通过response.read()可以读取到response里面的html,通过response.info()可以读到一些额外的信息。
-
12345678910
#!/usr/bin/env python
import
sys, urllib2
req
=
urllib2.Request(sys.argv[
1
])
response
=
urllib2.urlopen(req)
print
"Retrieved"
, response.geturl()
info
=
response.info()
for
key, value
in
info.items():
print
"%s = %s"
%
(key, value)
html
=
response.read()
print
html
2.在远程http服务器上验证
有些站点需要http认证后才能访问。最普通的认证类型是基本认证,由客户端向服务器器发送一个用户名和密码。http认证一般显示一个弹出窗口来询问用户名和密码,这与基于cookie和form的认证不同。
下面是一个例子,首先定义了一个扩展urllib2.HTTPPasswordMgr的类,允许在需要的时候询问用户名和密码,然后调用build_opener()指定一些额外处理,其实在urllib2.urlopen()内部调用了build_opener(),并且不带任何参数。所以在访问常规网站的时候urllib2.urlopen()等于opener.open()返回都一样。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
#!/usr/bin/env python
import
sys, urllib2, getpass
class
BasePassword(urllib2.HTTPPasswordMgr):
def
find_user_password(
self
, realm, authurl):
ret
=
urllib2.HTTPPasswordMgr.find_user_password(
self
, realm, authuri)
if
ret[
0
]
=
=
None
and
ret[
1
]
=
=
None
:
sys.stdout.write(
"Login reauired for %s at %sn"
%
(realm, authurl))
sys.stdout.write(
"Username: "
)
username
=
sys.stdin.readline().rstrip()
password
=
getpass.getpass().rstrip()
return
(username, password)
else
:
return
ret
req
=
urllib2.Request(sys.argv[
1
])
opener
=
urllib2.build_opener(urllib2.HTTPBasicAuthHandler(BasePassword()))
response
=
opener.
open
(req)
print
response.read()
|
3.表单提交(GET和POST)
有两种方法提交表单数据:GET和POST,取决于HTML文档中<form>标签里面的参数
GET实例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
#!/usr/bin/env python
import
sys, urllib2, urllib
keyword
=
sys.argv[
1
]
url
=
url
+
'?'
+
urllib.urlencode(
'http://www.xxx.com'
, [(
'query'
, keyword)])
req
=
urllib2.Request(url)
response
=
urllib2.urlopen(req)
print
response.read()
POST实例:
#!/usr/bin/env python
import
sys, urllib2, urllib
keyword
=
sys.argv[
1
]
url
=
'http://www.xxx.com'
data
=
urllib.urlencode([(
'query'
, keyword)])
req
=
urllib2.Request(url)
response
=
urllib2.urlopen(req, data)
|
更一般的提交数据,通过urllib2.Request()构造一个有额外数据的请求信息。包括“http header”和想要发送的数据,这些数据需要被以标准的方式encode,然后作为一个数据参数传送给Request对象。Encoding是在urllib中完成的,而不是在urllib2中完成的。
如下例:
-
12345678910
#!/usr/bin/env python
import
urllib, urllib2
url
=
'http://www.baidu.com'
user_agent
=
'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
values
=
{
'name'
:
'Michael Foord'
,
'location'
:
'Northampton'
,
'language'
:
'Python'
}
headers
=
{
'User-Agent'
: user_agent }
data
=
urllib.urlencode(values)
req
=
urllib2.Request(url, data, headers)
response
=
urllib2.urlopen(req)
the_page
=
response.read()
4.异常处理
捕获连接错误,在和远程Web服务器建立连接时,很多地方可能出现问题:提供的URL不对、URL使用了一个不支持的协议、主机名不存在、访问不到服务器或者服务器针对请求返回一个错误(例如:404)。
任何在连接过程中产生的异常要么是urllib2.URLError的实例,要么是它的一个子类。
-
123456789
#!/usr/bin/env python
import
sys, urllib2
req
=
urllib2.Request(sys.argv[
1
])
try
:
response
=
urllib2.urlopen(req)
except
urllib2.URLError, e:
print
"Error retrieving data:"
, e
sys.exit(
1
)
print
response.read()
5.非http协议通信(如FTP)
urllib2模块也支持非http协议。默认情况下支持http、ftp、gopher和机器本地硬盘上的文件,只是response.info()返回的报头会有所差异。