Python3使用request/urllib庫重定向問題


禁止自動重定向

python3的urllib.request模塊發http請求的時候,如果服務器響應30x會自動跟隨重定向,返回的結果是重定向后的最終結果而不是30x的響應結果。

request是靠HTTPRedirectHandler這個中的方法攔截重定並發起重新發起請求的,網上有方法說繼承這個類並把類下面的方法都改成pass,這樣可以阻止重定向,但是無法阻止30x響應被HTTPErrorProcessor類捕獲,會最終拋出異常。可以通過處理這個exception來解決,但是稍麻煩。

有沒有辦法讓302響應像200一樣不拋異常而返回response類對象呢?我看了一下urllib.request模塊的代碼,是可以很簡單地實現的。看代碼:

from urllib import request

class NoRedirHandler(request.HTTPRedirectHandler):
    def http_error_302(self, req, fp, code, msg, headers):
        return fp
    http_error_301 = http_error_302

# other_handler = ...
opener = request.build_opener( NoRedirHandler, other_handlers)
rsp = opener.open('http://example.com')

# rsp.code
#>> 302
# rsp.read()
#>> b''

主意上面的“other_handler”是個示例,你可能會把他替換成HTTPCookieProcessor或其他handler類實例或直接刪除它。

實際上就是http_error_302函數的fp這個傳參比較令人疑惑,我發現request這個庫里其他地方傳參給這個函數時這個pf其實就是response,只有在這里變成了pf,不知道作者是故意不想讓人改呢還是什么原因。

重定向攜帶cookie(會話)

request庫會自動跟隨重定向,返回新頁面的信息,但是如果重定向后的頁面需要會話信息(cookie),就可能導致重定向循環,直到重定向次數過多,拋出錯誤。

解決這個問題用上HTTPCookieProcessor,這樣請求會自動保存獲得的cookie並在后面使用,不需要自己去set header,全自動的。例:

from urllib import request

cookie_hdr = request.HTTPCookieProcessor()
opener = request.build_opener(cookie_hdr)
req = request.Request('http://example.com')
with opener.open(req) as f:
    # bla...bla...bla
    page_data = f.read()

CookieProcess也能支持把cookie放一個文件里,可以再程序重啟后保持之前的會話。


免責聲明!

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



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