Python HTTP 請求時對重定向中的 cookie 的處理

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

 
HTTPCookieProcessor
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?

相關文章
相關標籤/搜索