前篇介绍了直接使用httplib发送Cookie,简洁直观。创建cookielib.CookieJar对象自动管理Cookie稍繁琐一些,但是一旦创建,可供urllib2创建opener,后续的所有cookie更新和过期删除都是自动处理的。
1. 解析Cookie Str,得到Cookie.SimpleCookie对象
我们得到的Request Header中,Cookie是这样的格式:
Cookie: key1=val1; key2=val2; key3=val3
第一步是解析它,得到Cookie.SimpleCookie对象。通过字符串构造即可: Cookie.SimpleCookie(cookie_str)
得到的是一个dict-like对象,它的每一个值都是一个Set-Cookie语句,上述例子解析后是:
from Cookie import SimpleCookie
>>> sc = SimpleCookie('key1=val1; key2=val2; key3=val3')
>>> for c,v in sc.items():
... print c,v
...
key3 Set-Cookie: key3=val3
key2 Set-Cookie: key2=val2
key1 Set-Cookie: key1=val1
2. 用SimpleCookie创建cooklib.Cookie对象
上述SimpleCookie不能直接使用,因为一个完整的Cookie,还必须包括额外的字段,如:domain、path、expires等。第二步工作是创建cooklib.Cookie对象,直接将key, value传入cooklib.Cookie类的构造函数即可。
得到一系列cookielib.Cookie对象,便可以依次用它们来更新CookieJar了。
3. 完整的示例代码
import cookielib
import Cookie
import urllib2
def build_opener_with_cookie_str(cookie_str, domain, path='/'):
simple_cookie = Cookie.SimpleCookie(cookie_str) # Parse Cookie from str
cookiejar = cookielib.CookieJar() # No cookies stored yet
for c in simple_cookie:
cookie_item = cookielib.Cookie(
version=0, name=c, value=str(simple_cookie[c].value),
port=None, port_specified=None,
domain=domain, domain_specified=None, domain_initial_dot=None,
path=path, path_specified=None,
secure=None,
expires=None,
discard=None,
comment=None,
comment_url=None,
rest=None,
rfc2109=False,
)
cookiejar.set_cookie(cookie_item) # Apply each cookie_item to cookiejar
return urllib2.build_opener(urllib2.HTTPCookieProcessor(cookiejar)) # Return opener
if __name__ == '__main__':
cookie_str = 'tLargeScreenP=1; Authorization=Basic%20HereIsMySecret; subType=pcSub; TPLoginTimes=2'
opener = build_opener_with_cookie_str(cookie_str, domain='192.168.1.253')
html_doc = opener.open('http://192.168.1.253').read()
import re
print 'Open With Cookie:', re.search('(.*?)', html_doc, re.IGNORECASE).group(1)
html_doc = urllib2.urlopen('http://192.168.1.253').read()
print 'Open Without Cookie:', re.search('(.*?)', html_doc, re.IGNORECASE).group(1)
运行结果:
192.168.1.253是我房间的路由器,第一次使用带Cookie的Opener请求,第二次不带Cookie请求。