首先說明一下,我使用的是 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?