Ce face raise_for_status() și timeout
requests nu dă eroare când serverul răspunde cu 404 sau 500: primești un răspuns normal, cu status_code diferit de 200. r.raise_for_status() verifică pentru tine: dacă codul este între 400 și 599, aruncă requests.exceptions.HTTPError; altfel nu face nimic.
timeout=5 oprește cererea dacă serverul nu se conectează sau nu trimite date timp de 5 secunde și aruncă requests.exceptions.Timeout. Poți da și un tuplu (3, 10): 3 secunde pentru conectare, 10 pentru citire. Fără rețea sau cu un nume de server greșit primești ConnectionError.
Toate aceste excepții moștenesc requests.exceptions.RequestException, pe care o poți prinde la final, pentru orice altă problemă de rețea.
Parametri
| Parametru | Descriere |
|---|---|
timeout |
Număr de secunde sau tuplu (conectare, citire). |
HTTPError |
Aruncată de raise_for_status() pentru codurile 4xx și 5xx. |
Timeout |
Serverul nu a răspuns în timpul dat. |
ConnectionError |
Nu s-a putut face conexiunea (fără rețea, nume greșit, server oprit). |
RequestException |
Clasa de bază a tuturor excepțiilor requests. |
Ce returnează
raise_for_status() returnează None sau aruncă HTTPError.
Exemple
Exemplul 1: Succes, eroare 404 și timeout
Adresa /delay/5 răspunde după 5 secunde, dar cererea așteaptă doar 2.
import requests
adrese = [
"https://httpbin.org/status/200",
"https://httpbin.org/status/404",
"https://httpbin.org/delay/5",
]
for url in adrese:
try:
r = requests.get(url, timeout=2)
r.raise_for_status()
print("OK:", url)
except requests.exceptions.HTTPError as e:
print("Eroare HTTP:", e)
except requests.exceptions.Timeout:
print("Timeout:", url)
Rezultat posibil (diferă la fiecare rulare)
OK: https://httpbin.org/status/200
Eroare HTTP: 404 Client Error: NOT FOUND for url: https://httpbin.org/status/404
Timeout: https://httpbin.org/delay/5
Exemplul 2: O funcție care încearcă de mai multe ori
La erori de rețea sau timeout, funcția mai încearcă de două ori, apoi renunță. Erorile 4xx nu se reîncearcă: cererea e greșită.
import time
import requests
def descarca_curs(url, incercari=3):
for incercare in range(1, incercari + 1):
try:
r = requests.get(url, timeout=(3, 10))
r.raise_for_status()
return r.json()
except (requests.exceptions.Timeout, requests.exceptions.ConnectionError) as e:
print(f"Încercarea {incercare} a eșuat: {type(e).__name__}")
time.sleep(1)
raise RuntimeError("Serverul nu răspunde")
try:
print(descarca_curs("https://server-care-nu-exista.ro/curs.json"))
except RuntimeError as e:
print(e)
Rezultat posibil (diferă la fiecare rulare)
Încercarea 1 a eșuat: ConnectionError
Încercarea 2 a eșuat: ConnectionError
Încercarea 3 a eșuat: ConnectionError
Serverul nu răspunde
Greșeli frecvente
- Presupui că un răspuns fără excepție înseamnă succes. Un 404 sau 500 nu aruncă nimic dacă nu apelezi
raise_for_status()sau nu verificistatus_code. - Prinzi
except Exceptionpeste tot și ascunzi și greșelile din propriul cod. Prinde excepțiile dinrequests.exceptions. - Crezi că
timeout=10limitează toată descărcarea la 10 secunde. Limitează așteptarea între două bucăți de date; o descărcare lentă, dar continuă, poate dura mai mult.
Comenzi înrudite
requests.get(): Trimite o cerere HTTP GET și returnează răspunsul: cod de stare, antete, text sau JSON.requests.post(): Trimite date la un server prin HTTP POST: JSON pentru API-uri sau câmpuri de formular.raise: Aruncă (semnalează) o excepție, oprind execuția normală până când este prinsă cu except.