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.