Библиотека запросов Python перенаправляет новый URL

103

Я просматривал документацию по запросам Python, но не вижу никаких функциональных возможностей того, чего я пытаюсь достичь.

В моем сценарии я устанавливаю allow_redirects=True.

Я хотел бы знать, была ли страница перенаправлена ​​на что-то еще, каков новый URL.

Например, если начальный URL был: www.google.com/redirect

И конечный URL-адрес www.google.co.uk/redirected

Как мне получить этот URL?

Даниэль Пильч
источник
Посмотрите этот ответ, чтобы справиться с urllib2
крестраж

Ответы:

165

Вы ищете историю запросов .

response.historyАтрибут представляет собой список ответов , которые привели к окончательному URL, который можно найти в response.url.

response = requests.get(someurl)
if response.history:
    print("Request was redirected")
    for resp in response.history:
        print(resp.status_code, resp.url)
    print("Final destination:")
    print(response.status_code, response.url)
else:
    print("Request was not redirected")

Демо:

>>> import requests
>>> response = requests.get('http://httpbin.org/redirect/3')
>>> response.history
(<Response [302]>, <Response [302]>, <Response [302]>)
>>> for resp in response.history:
...     print(resp.status_code, resp.url)
... 
302 http://httpbin.org/redirect/3
302 http://httpbin.org/redirect/2
302 http://httpbin.org/redirect/1
>>> print(response.status_code, response.url)
200 http://httpbin.org/get
Мартейн Питерс
источник
httpbin.org по какой-то причине выдает 404, но httpbingo.org (та же схема URL-адресов) отлично работал у меня.
Престон Бадир,
1
@PrestonBadeer: это известная проблема: github.com/postmanlabs/httpbin/issues/617 . К счастью, неважно, что демонстрация работает для ответа.
Мартейн Питерс
69

Это ответ на несколько другой вопрос, но поскольку я сам застрял на этом, я надеюсь, что это может быть полезно для кого-то другого.

Если вы хотите использовать allow_redirects=Falseи перейти непосредственно к первому объекту перенаправления, а не следовать их цепочке, и вы просто хотите получить место перенаправления непосредственно из объекта ответа 302, тогда r.urlэто не сработает. Вместо этого это заголовок «Местоположение»:

r = requests.get('http://github.com/', allow_redirects=False)
r.status_code  # 302
r.url  # http://github.com, not https.
r.headers['Location']  # https://github.com/ -- the redirect destination
hwjp
источник
Спасибо - это увеличило мой скрипт перехода по URL (в котором были тысячи URL-адресов) на несколько секунд.
ahinkle
Вы знаете, в чем дело r.next? Я думал, что это будет содержать PreparedRequestуказание на URL-адрес перенаправления, но, похоже, это не так ...
Элиас Штрел
33

Я думаю, что при обработке перенаправления URL-адреса будет безопаснее вызывать request.head вместо requests.get , проверьте здесь проблему github :

r = requests.head(url, allow_redirects=True)
print(r.url)
Гэн Цзявэнь
источник
1
Это должен быть принятый ответ. Коротко и мило.
Volatil3 09
5
@ Volatil3: не все серверы отвечают на запрос HEAD так же, как на GET.
Blender
10

Для python3.5 вы можете использовать следующий код:

import urllib.request
res = urllib.request.urlopen(starturl)
finalurl = res.geturl()
print(finalurl)
Shuai.Z
источник
это правильный ответ для Python 3.5, мне потребовалось время, чтобы найти, спасибо
jjj