Pythonのurllib.requestでリダイレクトをさせない

urllib.request.urlopenメソッドはレスポンスが300番台だった場合、リダイレクトを実行してそのレスポンスを結果とする。 HTTPのステータスコード302のレスポンスを返すAPIを作ってるときに、リダイレクトを実行せずに、最初に返ってきた302レスポンスを取得したかった。

既定のオープナーではレスポンスが200以外のステータスコードのときHTTPErrorProcessorによって各ハンドラーに振り分けられる。 docs.python.org urllib.request.HTTPErrorProcessor

今回は何か処理をしたいのではなくてレスポンスを結果として取得したいだけ。HTTPErrorProcessorでの処理をステータスコード200のときと同じようにすればいい。

build_openerにHTTPErrorProcessorのサブクラスを渡せば既定のHTTPErrorProcessorの動作を置き換えることができる。

from urllib.request import build_opener, HTTPErrorProcessor

class Handler(HTTPErrorProcessor):
    def http_response(self, request, response):
        return response
    
    https_response = http_response

opener = build_opener(Handler())

with opener.open(req) as res:
    print(res.code)
    print(res.headers)

参考にした