首先说明一下,我使用的是 Python3 的 urllib,但 Python2.x 同理(使用 urllib2)。python
想用脚本去登陆一个网站。和不少网站同样,该网站使用 cookie 来保存会话信息。这个我之前是本身提取 response 中的 Set-Cookie
头来处理的。此次本想如法炮制,却发现没保存须要的 cookie,因此登陆失败。cookie
很郁闷地想了半天,最后出去 wireshark 抓包,终于发现原来重要的 cookie 在登陆后的应答中,但这个应答是个 302 重定向,因此 urllib 默认的 opener (urllib.request.urlopen)直接就跟从这个重定向了,没有对 cookie 进行任何处理。网站
我首先想到的是,不要跟从重定向。我看到有个 HTTPRedirectHandler
,但文档里没写它怎么用。郁闷……本身找到 request.py 文件看源代码,折腾了很久无果,遂想到 Google (早该想到了。。。)因而找到了 StackOverflow 上。有两个解决办法:要么不跟从重定向,要么弄个 HTTPCookieProcessor
保存 cookie 信息。看我本身的需求,固然选后者了。并且,那个回答问题的人也没有给出如何不让它跟从重定向(所给代码只是在重定向前对 cookie 进行处理而已)。url
因而,我再一次地打开了 http.cookiejar 的文档,尝试弄明白这东西到底怎么用。当初折腾 cookie 的时候,没弄明白这个,因此才本身处理的。spa
看 request.py 里的代码,这个 CookieJar 用起来至关不错:code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
class
HTTPCookieProcessor(BaseHandler):
def
__init__(
self
, cookiejar
=
None
):
import
http.cookiejar
if
cookiejar
is
None
:
cookiejar
=
http.cookiejar.CookieJar()
self
.cookiejar
=
cookiejar
def
http_request(
self
, request):
self
.cookiejar.add_cookie_header(request)
return
request
def
http_response(
self
, request, response):
self
.cookiejar.extract_cookies(response, request)
return
response
https_request
=
http_request
https_response
=
http_response
|
不过我须要将 cookie 信息保存到文件。从文档上看到有个 FileCookieJar
。我尝试了下,出错了,没有 _really_load
方法,我晕。。。以后才注意到其源代码开头有个ASCII图:ci
1
2
3
4
5
6
7
8
9
10
11
|
CookieJar____
/ \ \
FileCookieJar \ \
/ | \ \ \
MozillaCookieJar | LWPCookieJar \ \
| | \
| ---MSIEBase | \
| / | | \
| / MSIEDBCookieJar BSDDBCookieJar
|/
MSIECookieJar
|
原来具体实现还在子类啊。好吧,我就用 MozillaCookieJar
好了。文档
用法很简单,初始化时把文件名传给它,载入用 load()
,保存用 save()
。不过要注意的是,文件不存在时不能载入,touch 个空文件出来也不行的。get
另外,那个 StackOverflow 的页面还提到了 mechanize 这个模块,有时间去尝试下 :-)it
最后,若是我不要它重定向该怎么作呢?难道非要我去用更底层的 http.client?