web-dev-qa-db-ja.com

Pythonのurllib(2)がリダイレクトに従うのを防ぐ方法

現在、Pythonを使用してサイトにログインしようとしていますが、サイトは同じページでCookieとリダイレクトステートメントを送信しているようです。Python Pythonのurllib(またはurllib2)urlopenがリダイレクトを追跡しないようにするにはどうすればよいですか?

47
Jack Edmonds

いくつかのことができます:

  1. 各リダイレクトをインターセプトする独自のHTTPRedirectHandlerを構築します
  2. HTTPCookieProcessorのインスタンスを作成し、そのオープナーをインストールして、cookiejarにアクセスできるようにします。

これは両方を示す簡単な小さなことです

import urllib2

#redirect_handler = urllib2.HTTPRedirectHandler()

class MyHTTPRedirectHandler(urllib2.HTTPRedirectHandler):
    def http_error_302(self, req, fp, code, msg, headers):
        print "Cookie Manip Right Here"
        return urllib2.HTTPRedirectHandler.http_error_302(self, req, fp, code, msg, headers)

    http_error_301 = http_error_303 = http_error_307 = http_error_302

cookieprocessor = urllib2.HTTPCookieProcessor()

opener = urllib2.build_opener(MyHTTPRedirectHandler, cookieprocessor)
urllib2.install_opener(opener)

response =urllib2.urlopen("WHEREEVER")
print response.read()

print cookieprocessor.cookiejar
33
pope

必要なのがリダイレクトを停止する場合、それを行う簡単な方法があります。たとえば、Cookieのみを取得し、パフォーマンスを向上させるために、他のページにリダイレクトされるのは望ましくありません。また、コードが3xxのままであることを願っています。たとえば302を使用してみましょう。

class MyHTTPErrorProcessor(urllib2.HTTPErrorProcessor):

    def http_response(self, request, response):
        code, msg, hdrs = response.code, response.msg, response.info()

        # only add this line to stop 302 redirection.
        if code == 302: return response

        if not (200 <= code < 300):
            response = self.parent.error(
                'http', request, response, code, msg, hdrs)
        return response

    https_response = http_response

cj = cookielib.CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj), MyHTTPErrorProcessor)

この方法では、urllib2.HTTPRedirectHandler.http_error_302()に進む必要さえありません。

さらに一般的な場合は、単にリダイレクトを停止することです(必要に応じて):

class NoRedirection(urllib2.HTTPErrorProcessor):

    def http_response(self, request, response):
        return response

    https_response = http_response

通常、この方法で使用します。

cj = cookielib.CookieJar()
opener = urllib2.build_opener(NoRedirection, urllib2.HTTPCookieProcessor(cj))
data = {}
response = opener.open('http://www.example.com', urllib.urlencode(data))
if response.code == 302:
    redirection_target = response.headers['Location']
29
Alan Duan

_urllib2.urlopen_は、このハンドラクラスのリストを使用するbuild_opener()を呼び出します。

_handlers = [ProxyHandler, UnknownHandler, HTTPHandler,
HTTPDefaultErrorHandler, HTTPRedirectHandler,
FTPHandler, FileHandler, HTTPErrorProcessor]
_

HTTPRedirectHandlerを省略したリストで自分でurllib2.build_opener(handlers)を呼び出してから、結果に対してopen()メソッドを呼び出してURLを開くことができます。リダイレクトが本当に嫌いな場合は、urllib2.install_opener(opener)を独自の非リダイレクトオープナーに呼び出すこともできます。

あなたの本当の問題は、_urllib2_があなたが望む方法でcookieを実行していないということです。 使用方法Python Webページにログインし、後で使用するためにCookieを取得するには?

12
joeforker

この質問は here の前に尋ねられました。

編集: 風変わりなWebアプリケーションを処理する必要がある場合は、おそらく mechanize を試してください。 Webブラウザーをシミュレートする優れたライブラリです。リダイレクト、Cookie、ページの更新を制御できます... WebサイトがJavaScriptに(あまり)依存していない場合、mechanizeをうまく利用できます。

3
paprika