Pustaka Permintaan Python mengalihkan url baru

107

Saya telah melihat-lihat dokumentasi Permintaan Python tetapi saya tidak dapat melihat fungsionalitas apa pun untuk apa yang saya coba capai.

Dalam skrip saya, saya mengatur allow_redirects=True.

Saya ingin tahu apakah halaman tersebut telah dialihkan ke hal lain, apa URL barunya.

Misalnya, jika URL awalnya adalah: www.google.com/redirect

Dan URL finalnya adalah www.google.co.uk/redirected

Bagaimana cara mendapatkan URL itu?

Daniel Pilch
sumber
Lihat jawaban ini untuk berurusan dengan urllib2
horcrux

Jawaban:

169

Anda mencari riwayat permintaan .

The response.historyatribut adalah daftar tanggapan yang mengarah ke URL akhir, yang dapat ditemukan di 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")

Demo:

>>> 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
Martijn Pieters
sumber
httpbin.org memberikan 404 untuk beberapa alasan, tetapi httpbingo.org (skema URL yang sama) bekerja dengan baik untuk saya.
Preston Badeer
1
@PrestonBadeer: Ini adalah masalah yang diketahui: github.com/postmanlabs/httpbin/issues/617 . Untungnya, demo berfungsi untuk jawabannya, tidak penting.
Martijn Pieters
70

Ini menjawab pertanyaan yang sedikit berbeda, tetapi karena saya terjebak dalam masalah ini sendiri, saya harap ini berguna untuk orang lain.

Jika Anda ingin menggunakan allow_redirects=Falsedan mendapatkan langsung ke objek pengalihan pertama, daripada mengikuti rangkaiannya, dan Anda hanya ingin mendapatkan lokasi pengalihan langsung dari objek respons 302, maka r.urltidak akan berfungsi. Sebaliknya, ini adalah tajuk "Lokasi":

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
sumber
Terima kasih - ini meningkatkan skrip rujukan URL saya (yang memiliki ribuan url) beberapa detik.
Ahinkle
Tahukah kamu apa yang terjadi r.next? Saya pikir itu akan berisi PreparedRequestpetunjuk ke URL pengalihan, tetapi tampaknya bukan itu masalahnya ...
Elias Strehle
34

Saya pikir requests.head daripada requests.get akan lebih aman untuk dipanggil saat menangani pengalihan url, periksa masalah github di sini :

r = requests.head(url, allow_redirects=True)
print(r.url)
Geng Jiawen
sumber
1
Ini harus menjadi jawaban yang diterima. Pendek dan manis.
Volatil3
5
@ Volatil3: Tidak semua server menanggapi permintaan HEAD dengan cara yang sama seperti pada GET.
Blender
10

Untuk python3.5, Anda dapat menggunakan kode berikut:

import urllib.request
res = urllib.request.urlopen(starturl)
finalurl = res.geturl()
print(finalurl)
Shuai.Z
sumber
ini adalah jawaban yang benar untuk Python 3.5, saya butuh beberapa saat untuk menemukannya, terima kasih
jjj