Cara yang benar untuk mencoba / kecuali menggunakan modul permintaan Python?

Jawaban:

795

Lihat dokumen Permintaan pengecualian . Pendeknya:

Jika terjadi masalah jaringan (mis. Kegagalan DNS, koneksi ditolak, dll), Permintaan akan menimbulkan ConnectionErrorpengecualian.

Jika respons HTTP langka yang tidak valid, Permintaan akan memunculkan HTTPErrorpengecualian.

Jika permintaan habis, Timeoutpengecualian akan muncul.

Jika permintaan melebihi jumlah redirection maksimum yang dikonfigurasi, TooManyRedirectspengecualian dimunculkan.

Semua pengecualian yang secara eksplisit dimunculkan oleh Permintaan requests.exceptions.RequestException.

Untuk menjawab pertanyaan Anda, apa yang Anda tampilkan tidak akan mencakup semua basis Anda. Anda hanya akan menangkap kesalahan terkait koneksi, bukan kesalahan waktu itu.

Apa yang harus dilakukan ketika Anda mengetahui pengecualian benar-benar sesuai dengan desain skrip / program Anda. Apakah bisa diterima untuk keluar? Bisakah Anda melanjutkan dan mencoba lagi? Jika kesalahan adalah bencana besar dan Anda tidak dapat melanjutkan, maka ya, Anda dapat membatalkan program Anda dengan menaikkan SystemExit (cara yang bagus untuk mencetak kesalahan dan panggilan sys.exit).

Anda bisa menangkap pengecualian kelas dasar, yang akan menangani semua kasus:

try:
    r = requests.get(url, params={'s': thing})
except requests.exceptions.RequestException as e:  # This is the correct syntax
    raise SystemExit(e)

Atau Anda dapat menangkapnya secara terpisah dan melakukan hal yang berbeda.

try:
    r = requests.get(url, params={'s': thing})
except requests.exceptions.Timeout:
    # Maybe set up for a retry, or continue in a retry loop
except requests.exceptions.TooManyRedirects:
    # Tell the user their URL was bad and try a different one
except requests.exceptions.RequestException as e:
    # catastrophic error. bail.
    raise SystemExit(e)

Seperti yang ditunjukkan Christian :

Jika Anda ingin kesalahan http (mis. 401 Tidak Resmi) menimbulkan pengecualian, Anda dapat menelepon Response.raise_for_status. Itu akan memunculkan HTTPError, jika responsnya adalah kesalahan http.

Sebuah contoh:

try:
    r = requests.get('http://www.google.com/nothere')
    r.raise_for_status()
except requests.exceptions.HTTPError as err:
    raise SystemExit(err)

Akan dicetak:

404 Client Error: Not Found for url: http://www.google.com/nothere
Jonathon Reinhart
sumber
11
Jawaban yang sangat bagus untuk berurusan dengan spesifikasi pustaka permintaan, dan juga pengecualian umum.
Brian Peterson
10
Perhatikan bahwa karena bug di pustaka urllib3 yang mendasari, Anda juga harus menangkap socket.timeoutpengecualian jika Anda menggunakan batas waktu: github.com/kennethreitz/requests/issues/1236
jb.
15
Pembaca komentar masa depan: ini diperbaiki di Permintaan 2.9 (yang bundel urllib3 1.13)
RazerM
14
Jika Anda ingin kesalahan http (mis. 401 Tidak Resmi ) memunculkan pengecualian, Anda dapat menghubungi Response.raise_for_status . Itu akan meningkatkan HTTPError, jika responsnya adalah kesalahan http.
Christian Long
5
Daftar pengecualian di situs web Permintaan tidak lengkap. Anda dapat membaca daftar lengkapnya di sini .
Epoc
87

Satu saran tambahan harus eksplisit. Tampaknya lebih baik beralih dari spesifik ke umum ke tumpukan kesalahan untuk mendapatkan kesalahan yang diinginkan, jadi yang spesifik tidak bisa ditutup oleh kesalahan umum.

url='http://www.google.com/blahblah'

try:
    r = requests.get(url,timeout=3)
    r.raise_for_status()
except requests.exceptions.HTTPError as errh:
    print ("Http Error:",errh)
except requests.exceptions.ConnectionError as errc:
    print ("Error Connecting:",errc)
except requests.exceptions.Timeout as errt:
    print ("Timeout Error:",errt)
except requests.exceptions.RequestException as err:
    print ("OOps: Something Else",err)

Http Error: 404 Client Error: Not Found for url: http://www.google.com/blahblah

vs.

url='http://www.google.com/blahblah'

try:
    r = requests.get(url,timeout=3)
    r.raise_for_status()
except requests.exceptions.RequestException as err:
    print ("OOps: Something Else",err)
except requests.exceptions.HTTPError as errh:
    print ("Http Error:",errh)
except requests.exceptions.ConnectionError as errc:
    print ("Error Connecting:",errc)
except requests.exceptions.Timeout as errt:
    print ("Timeout Error:",errt)     

OOps: Something Else 404 Client Error: Not Found for url: http://www.google.com/blahblah
jouell
sumber
Apakah sintaks ini juga berlaku untuk postingan?
ScipioAfricanus
@ ScipioAfricanus ya.
andrea
10

Objek pengecualian juga berisi respons asli e.response, yang dapat berguna jika perlu melihat badan galat sebagai respons dari server. Sebagai contoh:

try:
    r = requests.post('somerestapi.com/post-here', data={'birthday': '9/9/3999'})
    r.raise_for_status()
except requests.exceptions.HTTPError as e:
    print (e.response.text)
tsh
sumber