PythonでURLをリクエストし、リダイレクトをたどらない簡単な方法はありますか?


96

urllib2のソースを見ると、HTTPRedirectHandlerをサブクラス化し、次にbuild_openerを使用してデフォルトのHTTPRedirectHandlerをオーバーライドするのが最も簡単な方法のように見えますが、これは多くの(比較的複雑な)作業のように思われます。ものすごく単純。


2
グーグルの場合:リクエストライブラリを使用すると、docs.python-requests.orgの頭痛が大幅に軽減され、以下のマリアンの回答を参照してください。非常にエレガントです。
Alojz Janez 2014

私はリクエストが最近行く方法であることに同意します。私はこのコメントとマリアンの回答に賛成票を投じましたが、当時最高だったので、回答は落札されたままにしておきます。
John

1
@Johnアワードはすばらしいですが、時間が経つにつれ、これはコミュニティ編集サイトです。焦点は人々ではなく良い答えです。彼は自分の賛成票を保持します。あなたはたくさんのプログラマーを非推奨のライブラリに誤解させています。
2014

1
わかりました。リクエストの回答を受け入れました。
ジョン

回答:


180

これがリクエストの方法です:

import requests
r = requests.get('http://github.com', allow_redirects=False)
print(r.status_code, r.headers['Location'])

5
それr.headers['Location']から、それがあなたをどこに送ったかを見るために見てください
パトリックスリー

リクエストはに正規化さLocationれるようlocationです。
ハミッシュ2017年

2
@Hamishをrequests使用すると、標準形式と小文字の両方でヘッダーにアクセスできます。docs.python-requests.org/en/master/user/quickstart/…を
Marian

1
2019年のPython 3では、これは私には機能しないようです。(キーディクテーションエラーが発生します。)
Max von Hippel '15

35

Dive Into Pythonには、urllib2を使用したリダイレクトの処理に関する優れた章があります。別の解決策はhttplibです。

>>> import httplib
>>> conn = httplib.HTTPConnection("www.bogosoft.com")
>>> conn.request("GET", "")
>>> r1 = conn.getresponse()
>>> print r1.status, r1.reason
301 Moved Permanently
>>> print r1.getheader('Location')
http://www.bogosoft.com/new/location

7
googleからここに来るすべての人、行く最新の方法はこれです:stackoverflow.com/a/14678220/362951リクエストライブラリはあなたの頭痛の多くを救います。
2014

「Dive Into Python」へのリンクは無効です。
guettli

11

これは、リダイレクトに従わないurllib2ハンドラーです。

class NoRedirectHandler(urllib2.HTTPRedirectHandler):
    def http_error_302(self, req, fp, code, msg, headers):
        infourl = urllib.addinfourl(fp, headers, req.get_full_url())
        infourl.status = code
        infourl.code = code
        return infourl
    http_error_300 = http_error_302
    http_error_301 = http_error_302
    http_error_303 = http_error_302
    http_error_307 = http_error_302

opener = urllib2.build_opener(NoRedirectHandler())
urllib2.install_opener(opener)

私はAPIのユニットテストを行っており、気にしないページにリダイレクトするログインメソッドを処理していますが、リダイレクトへの応答で目的のセッションCookieを送信していません。これはまさにそのために必要なものです。
Tim Wilder

9

リクエストメソッドのredirectionsキーワードはhttplib2赤ニシンです。最初のリクエストを返すのではなくRedirectLimit、リダイレクトステータスコードを受け取った場合は例外が発生します。最初の応答を返すには、オブジェクトにを設定follow_redirectsする必要があります。FalseHttp

import httplib2
h = httplib2.Http()
h.follow_redirects = False
(response, body) = h.request("http://example.com")

8

これは役立つと思います

from httplib2 import Http
def get_html(uri,num_redirections=0): # put it as 0 for not to follow redirects
conn = Http()
return conn.request(uri,redirections=num_redirections)

5

2つ目のoltのDive into Pythonへのポインタです。ここにurllib2リダイレクトハンドラーを使用した実装があります。多分、肩をすくめる。

import sys
import urllib2

class RedirectHandler(urllib2.HTTPRedirectHandler):
    def http_error_301(self, req, fp, code, msg, headers):  
        result = urllib2.HTTPRedirectHandler.http_error_301( 
            self, req, fp, code, msg, headers)              
        result.status = code                                 
        raise Exception("Permanent Redirect: %s" % 301)

    def http_error_302(self, req, fp, code, msg, headers):
        result = urllib2.HTTPRedirectHandler.http_error_302(
            self, req, fp, code, msg, headers)              
        result.status = code                                
        raise Exception("Temporary Redirect: %s" % 302)

def main(script_name, url):
   opener = urllib2.build_opener(RedirectHandler)
   urllib2.install_opener(opener)
   print urllib2.urlopen(url).read()

if __name__ == "__main__":
    main(*sys.argv) 

3
間違っているように見えます...このコードは実際にはリダイレクトに従い(元のハンドラーを呼び出し、HTTPリクエストを発行することにより)、例外を発生させます
CarlesBarrobésMar

5

しかし、最短の方法は

class NoRedirect(urllib2.HTTPRedirectHandler):
    def redirect_request(self, req, fp, code, msg, hdrs, newurl):
        pass

noredir_opener = urllib2.build_opener(NoRedirect())

1
これはどのように最短の方法ですか?インポートや実際のリクエストも含まれていません。
マリアン

私はすでにこのソリューションを投稿するつもりでしたが、この答えが一番下にあることにかなり驚いていました。それは非常に簡潔であり、私の意見では最高の答えになるはずです。
ユーザー

さらに、それはあなたにあなたにもっと自由を与えます、このように、これは従うべきURLを制御することが可能です。
ユーザー

確かに、これは簡単な方法です。デバッグしたい人のための短い発言。:のようなオープナーbulldingときに倍数ハンドラを設定することを忘れてはいけないとの。最後に:opener = urllib.request.build_opener(debugHandler, NoRedirect())debugHandler=urllib.request.HTTPHandler()debugHandler.set_http_debuglevel (1)urllib.request.install_opener(opener)
StashOfCode
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.