Вопрос по redirect, python, http – Есть ли простой способ запросить URL в Python и НЕ следовать перенаправлениям?

69

Глядя на источник urllib2, кажется, что самый простой способ сделать это - создать подкласс HTTPRedirectHandler, а затем использовать build_opener, чтобы переопределить HTTPRedirectHandler по умолчанию, но это кажется большой (относительно сложной) работой, выполняющей то, что должно быть довольно просто

Я согласен, что запросы - это путь, которым нужно идти в эти дни. Я одобрил этот комментарий и ответ Мариана, но оставляю ответ за вознаграждение, так как он был лучшим в то время. John
Для googlers: использование библиотеки запросов избавит вас от головной боли:docs.python-requests.org и посмотрите ответ Мариана ниже, он очень элегантный. Alojz Janez
Награды @John хорошие, но время идет, и это сайт, отредактированный сообществом. Основное внимание уделяется хорошим ответам, а не людям. Он сохранит свои очки голосов. Вы вводите в заблуждение тонны коллег-программистов в устаревших библиотеках. mit
Хорошо, достаточно справедливо. Я принял ответ на запросы. John

Ваш Ответ

7   ответов
33

Погружение в Python есть хорошая глава по обработке перенаправлений с urllib2. Другое решениеHTTPLIB.

>>> import httplib
>>> conn = httplib..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
Все, кто приходит сюда из Google, пожалуйста, обратите внимание, что современный способ это:stackoverflow.com/a/14678220/362951 Библиотека запросов избавит вас от головной боли.
Ссылка на "Dive Into Python" мертв.
7

redirections Ключевое слово вhttplib2 Метод запроса - красная сельдь. Вместо того, чтобы возвращать первый запрос, он вызоветRedirectLimit исключение, если он получает код состояния перенаправления. Для возврата первоначального ответа необходимо установитьfollow_redirects вFalse наHttp объект:

h = httplib2.Http()
h.follow_redirects = False
(response, body) = h.request("http://example.com")
Почему так мало голосов? Это то, что работает для меня.
5

Погрузитесь в 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) 
Выглядит неправильно ... Этот код на самом деле следует перенаправлениям (вызывая оригинальный обработчик, тем самым выполняя запрос HTTP), а затем вызывает исключение
11

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 с ответом на перенаправление. Это именно то, что мне нужно для этого.
5

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

noredir_opener = urllib2.build_opener(NoRedirect())
Как это самый короткий путь? Он даже не содержит импорт или фактический запрос.
Я уже собирался опубликовать это решение и был довольно удивлен, найдя этот ответ внизу. Это очень кратко и должно быть главным ответом на мой взгляд.
Более того, это дает вам больше свободы, так что это возможноcontrol which URLs to follow.
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)
125

Запросы путь:

import requests
r = requests.get('http://github.com', allow_redirects=False)
print(r.status_code, r.headers['Location'])
Обратите внимание, что кажется, что запросы нормализуютсяLocation вlocation.
@Hamishrequests позволяет получить доступ к заголовкам как в канонической форме, так и в нижнем регистре. Увидетьdocs.python-requests.org/en/master/user/quickstart/…
Тогда посмотрите наr.headers['Location'] чтобы увидеть, куда он тебя послал

Похожие вопросы