URL访问的扩展库—— urllib2¶
urllib2 主要用于基础和摘要式的身份验证,网页跳转,网页 cookie 等等。
urllib2.urlopen(url, [,data][,timeout])url字符串 /
Request对象。警告
HTTPS 请求不进行服务器认证
data取值为字符串或者
None,定义传递给服务器的用户数据。重要
目前为止,HTTP 请求是唯一用到
data参数的用户请求;data不为None时,HTTP 请求为POST方式。data必须符合application/x-www-form-urlencoded格式规范。 例如:name='hwz'®ion='beijing'可以调用函数
urllib.urlencode()做数据格式转换:1 2 3 4 5
import urllib dic = {"name":"hwz", "region":"beijing"} encoded_data = urllib.urlencode(dic) print encoded_data # 'region=beijing&name=hwz'
urllib.urlencode()的输入参数为字典或者二元组序列,返回的是application/x-www-form-urlencoded格式的字符串。 urllib2 模块支持 HTTP/1.1 版本的请求,请求头中带有 Connection:close 键值。timeout指定连接超时时间(s),等待连接是阻塞式的; 若没有指定,使用的是全局默认的数值。
重要
该参数仅对 HTTP, HTTPS 和 FTP 连接起作用。
返回值
返回一个仿文件对象,指向的是服务器的响应消息。
注解
服务器的 HTTP 响应消息,包括响应头(元信息)和响应体(也就是数据资源)。 响应体可以是
text/html文档,也就是浏览器中的网页的源代码; 也可以是图片资源,还可以是二进制的数据,或者application/json字符串等等。返回对象除了常规文件读写方法之外,还提供两个额外的方法:
geturl()
获取服务器返回的资源对应的 URL;URL 指含有该资源的网址; 比如网页资源,则返回该网页的 URL:
1 2
response = urllib2.open('http://www.baidu.com') print response.geturl() # 'http://www.baidu.com'
info()
返回服务器响应的元信息,比如响应头信息。 其格式是
mimetools.Message。可以通过键名获取响应头信息,比如:
1 2 3
response = urllib2.open('http://www.baidu.com') meta_data = response.info() print meta_data.getheaders('Content-Type') # ['text/html; charset=utg-8']
异常
URLError
urllib2.install_opener(opener)手动安装全局访问器。
重要
系统默认安装的全局访问器,使用
UnknownHandler请求处理器; 如果设置了*_proxy环境变量(例如set http_proxy=*),全局访问器使用的ProxyHandler。用
<OpenerDirector instance>.open()代替urlopen(),可以不用安装全局访问器。urllib2.build_opener([handler,...])返回一个访问器对象。
访问器内部设置了请求处理器列表,可以通过
handler,...手动设置处理列表。handler,...是BaseHandler的实例/不带参数的子类。以下请求处理器将自动排在
handler,...前面(出现在handler,...中的除外):ProxyHandlerUnknownHandlerHttpHandlerHttpDefaultErrorHandlerHttpRedircetHandlerFTPHandlerFileHandlerHTTPErrorProcessor
如果安装 Python 的时候支持 SSL(即可以加载
ssl模块),还会加入HTTPSHandler。urllib2.Request(url, [data][,headers][,origin_req_host][,unverifiable])注解
请求类
urlURL 字符串。
data与
urllib2.urlopen()的data参数说明一致headersheaders是一个字典。对于
headers的处理,相当于调用add_header(); 表示给请求头添加新的键值对,比如指定User-Agent键值对。注解
服务器可以利用
User-Agent字段过滤请求。 例如,Mozilla 火狐浏览器的User-Agent为Mozilla/5.0 (X11; U; Linux i686) Gecko/20071127 FireFox/2.0.0.11; 而urllib2的User-Agent默认为Python-urllib/*.*。 如果某个服务器只接受User-Agent为Mozilla/5.0 (X11; U; Linux i686) Gecko/20071127 FireFox/2.0.0.11的请求, 则使用urllib2的脚本发起的网络请求会被过滤掉。这样做的好处是可以让服务器只接受来自浏览器的请求,而不是脚本发起的请求。 当然这种限制也不是绝对的,可以手动修改
User-Agent键值达到目的。 因此,Python 文档用了spoof这个词(“糊弄”User-Agent)。
最后两个参数和三方的
HTTP cookies解析有关:origin_req_host默认为
cookielib.request_host(self),表示请求指定的服务器主机名或者 IP 地址。 例如,如果请求的是 HTML 文档,则该参数是目标网页的主机名:1 2 3
import urllib2, cookielib request = urllib2.Request('http://www.baidu.com') host_name = cookielib.request_host(request) # 'www.baidu.com'
unverifiable表示请求是否可验证(RFC 2965),默认为False。 对于一个不可验证的请求对应的 URL,用户是无权决定是否访问的。 例如,请求 HTML 文档中的图片,用户无权决定是否自动获取该图片,则这个参数设为True注意
许多网页就是这样,不受用户控制,自动弹出。
Request 实例¶
包含以下公有方法:
add_data(data)get_method()"POST"/"GET"/...,仅对 HTTP 请求有意义。has_data()get_data()add_header(key,val)给请求头添加新的键值对,只有 HTTP 处理器会受理这些键值对。
注解
键名不能相同,如果相同,则后一次的键值会覆盖前一次的键值。
add_unredirected_header(key,header)添加一个键值对;如果需要做重定向,该键值对不会加入到重定向请求头中has_header(header)请求头中是否含有指定键值对get_full_url()返回构造函数提供的 URLget_type()返回协议类型get_host()返回主机名get_selector()获取 URL 选择子set_proxy(host, type)设置一个代理服务器,表示将生成一个代理请求实例。注解
host覆盖get_host()的返回值;type覆盖get_type()的返回值; 选择子是get_full_url()的返回值。get_origin_req_host()返回原始主机名(RFC 2965)。is_unverifiable()请求是否可验证。
OpenerDirector 实例¶
add_handler(handler)增加一个处理器。
处理器将添加以下操作序列:
protocol_open()打开协议 URLs;http_error_type()处理 HTTP 错误对应的错误类型;protocol_error()处理协议错误(HTTP 处理器会忽略该函数);protocol_request()预处理协议请求;protocol_response()后处理协议响应;
open(url[,data][,timeout])注解
和
urlopen()一样,不同的是,本函数使用局部访问器error(proto[,arg[,...]])proto指定协议类型;用协议指定的错误处理器处理当前协议错误。 返回一个收集错误信息的仿文件对象。
注解
HTTP 协议使用响应状态码指定错误处理器。
OpenerDirector 实例打开 URL 的几个阶段:
调用所有处理器的
protocol_request,预处理请求。调用所有处理器的
protocol_open,解析请求。如果某个处理器返回非
None值(即服务器响应),或者抛出异常(通常为URLError),这个阶段结束。 发生的异常允许继续传递。事实上,以上算法先尝试
default_open(); 如果都返回None,再尝试protocol_open(); 如果返回None,则再尝试unknown_open()。处理器调用
protocol_response,用于后处理响应。
BaseHandler 实例¶
BaseHandler 实例提供两个基础方法,可以直接调用:
add_parent(director)添加一个访问器close()删除所有访问器
重要
以下属性和方法只能在派生类中实现或使用:
parent 指定的
OpenerDirector实例default_open(req)
派生类如果想获取所有的 URL,必须实现这个方法。
派生类如果实现了这个方法,则会被
add_parent()指定的访问器对象调用。 它返回一个仿文件对象(如果没有访问器,则返回None)。抛出异常
URLError。重要
该方法在所有打开方法(
*_open())之前调用protocol_open(req)
注解
该方法的名称依据协议来定; 之后凡是
protocol_开头的方法都是跟随协议名称的,不再复述。比如: HTTP 协议的打开方法为
http_open(); ftp 协议的打开方法为ftp_open()等。派生类如果想用指定的协议解析 URL,必须实现这个方法。
派生类如果实现了这个方法,则会被
add_parent()指定的访问器对象调用。 它返回一个仿文件对象(如果没有访问器,则返回None)。unknown_open(req)派生类如果想不用任何处理器获取所有的 URL,必须实现这个方法。
参数说明和返回值以及异常类型和
protocol_open()一样。http_error_default(req, fp, code, msg, hdrs)
派生类如果想捕获所有 HTTP 错误码,必须实现这个方法。
派生类如果实现了这个方法,则会被
add_parent()指定的访问器对象调用。警告
用户不能调用这个方法
reqRequest实例fp仿文件对象,指向 HTTP 错误消息体code三个数字表示的错误码msg用户可见的错误码的解释文字hdrs一个字典对象,表示错误头的键值对
返回值与异常类型和
urlopen()相同。http_error_nnn(req, fp, code, msg, hdrs)派生类如果想捕获 HTTP 错误码
nnn,必须实现这个方法。派生类如果实现了这个方法,发生错误码
nnn时,add_parent()指定的访问器对象会自动调用对应的http_error_nnn()方法。参数说明和返回值以及异常类型和
http_error_default()一样。protocol_request(req)如果派生类想要预处理指定协议的请求实例,必须实现这个方法。
派生类如果实现了这个方法,则会被
add_parent()指定的访问器对象调用。req是预处理前的Request实例,返回的是预处理后的Request实例。protocol_response(req, response)派生类如果想后处理指定协议的服务器响应,必须实现这个方法。
派生类如果实现了这个方法,则会被
add_parent()指定的访问器对象调用。req是一个Request实例response有和urlopen()返回的对象一样的方法。
HTTPRedircetHandler 实例¶
redirect_request(req, fp, code, msg, hdrs, newurl)返回一个
Request实例或者None。如果服务器返回一个重定向的响应(即错误响应消息
301302等等), 则在方法http_error_30*()中自动调用redirect_request()方法。 然后用生成的请求实例发出新的网络请求,以重定向到新的 URL。 如果没有处理器可以解析新的 URL,则抛出HTTPError异常; 如果HTTPRedircetHandler不能解析新的 URL,但存在其他处理器可以解析,则返回None。http_error_301(req, fq, code, msg, hdrs)当服务器返回
moved permanently消息时,add_parent()指定的访问器会调用http_error_301()。http_error_302(req, fp, code, msg, hdrs)当服务器返回
found消息时,add_parent()指定的访问器会调用http_error_301()。http_error_303(req, fp,code, msg, hdrs)当服务器返回
see other消息时,add_parent()指定的访问器会调用http_error_301()。http_error_307(req, fp, code, msg, hdrs)当服务器返回
temporary redirect消息时,add_parent()指定的访问器会调用http_error_301()。