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


首先說明一下,我使用的是 Python3 的 urllib,但 Python2.x 同理(使用 urllib2)。

想用腳本去登錄一個網站。和很多網站一樣,該網站使用 cookie 來保存會話信息。這個我以前是自己提取 response 中的 Set-Cookie 頭來處理的。這次本想如法炮制,卻發現沒保存需要的 cookie,所以登錄失敗。

很郁悶地想了半天,最后出去 wireshark 抓包,終於發現原來重要的 cookie 在登錄后的應答中,但這個應答是個 302 重定向,所以 urllib 默認的 opener (urllib.request.urlopen)直接就跟從這個重定向了,沒有對 cookie 進行任何處理。

我首先想到的是,不要跟從重定向。我看到有個 HTTPRedirectHandler,但文檔里沒寫它怎么用。郁悶……自己找到 request.py 文件看源代碼,折騰了好久無果,遂想到 Google (早該想到了。。。)於是找到了 StackOverflow 上。有兩個解決辦法:要么不跟從重定向,要么弄個 HTTPCookieProcessor 保存 cookie 信息。看我自己的需求,當然選后者了。而且,那個回答問題的人也沒有給出如何不讓它跟從重定向(所給代碼只是在重定向前對 cookie 進行處理而已)。

於是,我再一次地打開了 http.cookiejar 的文檔,嘗試弄明白這東西到底怎么用。當初折騰 cookie 的時候,沒弄明白這個,所以才自己處理的。

看 request.py 里的代碼,這個 CookieJar 用起來相當不錯:

 
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圖:

 
1
2
3
4
5
6
7
8
9
10
11
                        CookieJar____
                        /     \      \
            FileCookieJar      \      \
             /    |   \         \      \
MozillaCookieJar | LWPCookieJar \      \
                  |               |      \
                  |   ---MSIEBase |       \
                  |  /      |     |        \
                  | /   MSIEDBCookieJar BSDDBCookieJar
                  |/
               MSIECookieJar

原來具體實現還在子類啊。好吧,我就用 MozillaCookieJar 好了。

用法很簡單,初始化時把文件名傳給它,載入用 load(),保存用 save()。不過要注意的是,文件不存在時不能載入,touch 個空文件出來也不行的。

另外,那個 StackOverflow 的頁面還提到了 mechanize 這個模塊,有時間去嘗試下 :-)

最后,如果我不要它重定向該怎么做呢?難道非要我去用更底層的 http.client?


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM