파이썬으로 URL을 요청하고 리디렉션을 따르지 않는 쉬운 방법이 있습니까?


100

urllib2의 소스를 살펴보면 가장 쉬운 방법은 HTTPRedirectHandler를 하위 클래스로 분류 한 다음 build_opener를 사용하여 기본 HTTPRedirectHandler를 재정의하는 것입니다. 그러나 이것은해야 할 것처럼 보이는 작업을 수행하기 위해 많은 (상대적으로 복잡한) 작업처럼 보입니다. 아주 간단합니다.


2
Google 직원의 경우 : 요청 라이브러리를 사용하면 docs.python-requests.org 와 같은 많은 두통을 줄일 수 있으며 아래 Marian의 답변을 볼 수 있습니다. 매우 우아합니다.
Alojz Janez 2014

나는 요청이 요즘 갈 길이라는 데 동의합니다. 이 댓글과 Marian의 답변을 찬성했지만 당시 최고 였기 때문에 답변을 수여 한 그대로 남겨두고 있습니다.
John

1
@John상은 좋지만 시간이 지남에 따라 커뮤니티 편집 사이트입니다. 초점은 사람이 아닌 좋은 답변에 있습니다. 그는 자신의 업 보트 포인트를 유지할 것입니다. 많은 동료 코더를 사용하지 않는 라이브러리로 오도하고 있습니다.
mit

1
좋습니다. 요청 답변을 수락했습니다.
John

답변:


184

요청 방법 은 다음과 같습니다 .

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

6
그런 다음 볼 r.headers['Location']이 당신에게 보낸 것 곳을보고
patricksurry

참고는 요청이 정상화 것으로 보인다 Locationlocation.
Hamish

2
@Hamish를 requests사용하면 표준 형식과 소문자 모두 헤더에 액세스 할 수 있습니다. docs.python-requests.org/en/master/user/quickstart/…
Marian

1
2019 년부터 Python 3에서 이것은 더 이상 저에게 작동하지 않는 것 같습니다. (핵심 dict 오류가 발생합니다.)
Max von Hippel

36

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 요청 라이브러리는 많은 두통을 덜어줍니다.
mit

"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를 단위 테스트하고 내가 신경 쓰지 않는 페이지로 리디렉션하는 로그인 메서드를 처리하고 있지만 리디렉션에 대한 응답과 함께 원하는 세션 쿠키를 보내지 않습니다. 이것이 바로 내가 필요한 것입니다.
Tim Wilder

9

요청 방법 의 redirections키워드 httplib2는 붉은 청어입니다. 첫 번째 요청을 반환하는 대신 RedirectLimit리디렉션 상태 코드를 수신하면 예외 가 발생합니다. 당신이 설정해야 inital 응답 돌아가려면 follow_redirectsFalseHttp객체를 :

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

두 번째로 Dive into Python에 대한 olt의 포인터 입니다. 다음은 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 요청을 발행함으로써) 예외를 발생
시킵니다

5

그러나 가장 짧은 방법은

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

noredir_opener = urllib2.build_opener(NoRedirect())

1
이것이 가장 짧은 방법은 무엇입니까? 가져 오기 또는 실제 요청도 포함하지 않습니다.
Marian

나는 이미이 솔루션을 게시 할 예정 이었으며이 답변을 맨 아래에서 찾은 것에 매우 놀랐습니다. 매우 간결하며 제 생각에는 최고의 답변이되어야합니다.
사용자

또한 더 많은 자유를 제공 하므로 팔로우 할 URL을 제어 할 수 있습니다 .
사용자

나는 이것이 쉬운 방법임을 확인합니다. 디버깅하려는 사람들을위한 짧은 설명입니다. 다음 과 같이 오프너를 불링 할 때 다중 핸들러를 설정할 수 있음을 잊지 마십시오. opener = urllib.request.build_opener(debugHandler, NoRedirect())where debugHandler=urllib.request.HTTPHandler()and debugHandler.set_http_debuglevel (1). 결국 :urllib.request.install_opener(opener)
StashOfCode
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.