Biblioteka żądań Pythona przekierowuje nowy adres URL


102

Przeglądałem dokumentację Python Requests, ale nie widzę żadnej funkcjonalności dla tego, co próbuję osiągnąć.

W moim skrypcie ustawiam allow_redirects=True.

Chciałbym wiedzieć, czy strona została przekierowana na coś innego, jaki jest nowy adres URL.

Na przykład, jeśli początkowy adres URL to: www.google.com/redirect

A końcowy URL to www.google.co.uk/redirected

Jak uzyskać ten adres URL?


Sprawdź tę odpowiedź, aby poradzić sobie z urllib2
horkruksa

Odpowiedzi:


165

Szukasz historii żądań .

response.historyAtrybut jest lista odpowiedzi, które doprowadziły do ostatecznej zawartości, którą można znaleźć w 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")

Próbny:

>>> 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 podaje 404 z jakiegoś powodu, ale httpbingo.org (ten sam schemat adresu URL) działał dobrze dla mnie.
Preston Badeer

@PrestonBadeer: To znany problem: github.com/postmanlabs/httpbin/issues/617 . Na szczęście nie jest istotne, że wersja demonstracyjna działa w odpowiedzi.
Martijn Pieters

69

To odpowiedź na nieco inne pytanie, ale skoro sam utknąłem w tym, mam nadzieję, że może to być przydatne dla kogoś innego.

Jeśli chcesz użyć allow_redirects=Falsei dostać się bezpośrednio do pierwszego obiektu przekierowania, zamiast podążać za ich łańcuchem, i po prostu chcesz uzyskać lokalizację przekierowania bezpośrednio z obiektu odpowiedzi 302, to r.urlnie zadziała. Zamiast tego jest to nagłówek „Lokalizacja”:

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

Dziękuję - to przyspieszyło mój skrypt odsyłający do adresu URL (który miał tysiące adresów URL) o kilka sekund.
ahinkle

Czy wiesz, o co chodzi r.next? Myślałem, że będzie to PreparedRequestwskazanie na adres URL przekierowania, ale wydaje się, że tak nie jest ...
Elias Strehle


33

Myślę, że request.head zamiast request.get będzie bezpieczniejsze do wywołania podczas obsługi przekierowania adresu URL, sprawdź tutaj problem z github :

r = requests.head(url, allow_redirects=True)
print(r.url)

1
To powinna być akceptowana odpowiedź. Krótkie i słodkie.
Volatil3

5
@ Volatil3: Nie wszystkie serwery odpowiadają na żądanie HEAD w taki sam sposób, jak w przypadku GET.
Blender

10

W przypadku pythona 3.5 możesz użyć następującego kodu:

import urllib.request
res = urllib.request.urlopen(starturl)
finalurl = res.geturl()
print(finalurl)

to jest poprawna odpowiedź dla Pythona 3.5, zajęło mi trochę czasu znalezienie, dzięki
jjj
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.