Quickstart¶
Chcesz zacząć? Ta strona to dobre wprowadzenie jak zacząć pracować z Requests. To wprowadzenie zakład, że już zainstalowałeś Requests. Jeśli tego jeszcze nie zrobiłeś, sprawdź sekcję Instalacja.
Po pierwsze, upewnij się, że:
- Requests są zainstalowane
- Requests są aktualne
Zacznijmy od kilku prostych przykładów.
Wykonaj Żądanie¶
Wykonywanie żądania z Requests jest bardzo proste.
Zacznij od zaimportowania modułu Requests:
>>> import requests
Teraz spróbujemy pobrać stronę. W tym przykładzie, spróbujmy pobrać publiczną oś czasu na GitHubie:
>>> r = requests.get('https://github.com/timeline.json')
Teraz mamy obiekt klasy Response zwany r. Możemy uzyskać wszelkie
potrzebne informacje z tego obiektu.
Proste API Requests oznacza, że wszystkie formy żądań HTTP są równie oczywiste. Na przykład, tak wykonuje się żądanie POST:
>>> r = requests.post("http://httpbin.org/post")
Nieźle, prawda? A jak wykonuje się inne żądania HTTP: PUT, DELETE, HEAD i OPTIONS? Równie prosto:
>>> r = requests.put("http://httpbin.org/put")
>>> r = requests.delete("http://httpbin.org/delete")
>>> r = requests.head("http://httpbin.org/get")
>>> r = requests.options("http://httpbin.org/get")
To jest dobre, ale to dopiero początek tego, co może zrobić Requests.
Podawanie parametrów w URL-ach¶
Bardzo często chcesz wysłać jakieś dane w ciągu zapytania URL-a. Jeśli
konstruowałbyś URL ręcznie, byłyby to pary klucz/wartość w URL-u po znaku
zapytania, np. httpbin.org/get?key=val.
Requests pozwala podawać te argumenty jako słownik (dict), używając keyword
argumentu params. Na przykład, jeśli chciałbyś przekazać
key1=value1 i key2=value2 do httpbin.org/get, użyłbyś poniższego
kodu:
>>> payload = {'key1': 'value1', 'key2': 'value2'}
>>> r = requests.get("http://httpbin.org/get", params=payload)
Możesz zobaczyć, że URL został poprawnie zakodowany przez wydrukowanie URL-a:
>>> print r.url
http://httpbin.org/get?key2=value2&key1=value1
Zauważ, że klucz o wartości None nie zostanie dodany do URL-a.
Zawartość odpowiedzi¶
Możemy przeczytać zawartość odpowiedzi serwera. Skorzystamy ponownie z osi czasu z GitHuba:
>>> import requests
>>> r = requests.get('https://github.com/timeline.json')
>>> r.text
u'[{"repository":{"open_issues":0,"url":"https://github.com/...
Requests automatycznie zdekoduje treść z serwera. Większość charsetów Unicode jest poprawnie i bezszwowo dekodowana.
Kiedy wykonujesz żądanie, Requests inteligentnie zgaduje kodowanie na podstawie
nagłówków HTTP. To kodowanie jest używane przez r.text. Możesz dowiedzieć
się, jakiego kodowanie Requests używa, i je zmienić, używając własności
r.encoding:
>>> r.encoding
'utf-8'
>>> r.encoding = 'ISO-8859-1'
Jeśli zmienisz kodowanie, Requests użyje nowej wartości r.encoding przy
whenever you call r.text.
Requests może też używać twoich własnych kodowań jeśli będziesz ich
potrzebował. Jeśli stworzyłeś swoje własne kodowanie i zarejestrowałeś je w
module codecs, możesz po prostu użyć nazwy kodeka jako wartość
r.encoding i Requests zajmie się dekodowaniem za ciebie.
Binarna zawartość odpowiedzi¶
Możesz też uzyskać dostęp do body odpowiedzi jako bajty, dla żądań nietekstowych:
>>> r.content
b'[{"repository":{"open_issues":0,"url":"https://github.com/...
Transfer-encodings: gzip i deflate są automatycznie dekodowane.
Na przykład, jeśli chcesz stworzyć obrazek z danych binarnych, możesz użyć poniższego kodu:
>>> from PIL import Image
>>> from StringIO import StringIO
>>> i = Image.open(StringIO(r.content))
Zwartość odpowiedzi JSON¶
Istnieje też wbudowany dekoder JSON, jeśli zajmujesz się danymi JSON:
>>> import requests
>>> r = requests.get('https://github.com/timeline.json')
>>> r.json()
[{u'repository': {u'open_issues': 0, u'url': 'https://github.com/...
Jeśli dekodowanie JSON nie powiedzie się, r.json podnosi wyjątek. Na
przykład, jeśli odpowiedź wyniesie 401 (Unauthorized), próba użycia r.json
podnosi ValueError: No JSON object could be decoded
Surowa zawratość odpowiedzi¶
Jeśli chcesz otrzymać surową odpowiedź socket od serwera (a zazwyczaj nie
chcesz), możesz użyć r.raw. Jeśli chcesz to zrobić, upewnij się, że
ustawiłeś stream=True w twoim oryginalnym żądaniu. Jeśli to uczynisz,
możesz zrobić tak:
>>> r = requests.get('https://github.com/timeline.json', stream=True)
>>> r.raw
<requests.packages.urllib3.response.HTTPResponse object at 0x101194810>
>>> r.raw.read(10)
'\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03'
Własne nagłówki¶
Jeśli chciałbyś dodać własne nagłówki HTTP do żądania, po prostu użyj parametru headers i umieść nagłówki w słowniku (dict).
Na przykład, nie podaliśmy content-type w poprzednim przykładzie:
>>> import json
>>> url = 'https://api.github.com/some/endpoint'
>>> payload = {'some': 'data'}
>>> headers = {'content-type': 'application/json'}
>>> r = requests.post(url, data=json.dumps(payload), headers=headers)
Bardziej skompliowane żądania POST¶
Zazwyczaj, chcesz wysłać dane form-encoded — na przykład z formularza w HTML.
Aby to zrobić, po prostu przekaż słownik do argumentu data. Twój słownik
danych będzie automatycznie zakodowany w formacie formularzy kiedy żądanie
zostanie wykonane:
>>> payload = {'key1': 'value1', 'key2': 'value2'}
>>> r = requests.post("http://httpbin.org/post", data=payload)
>>> print r.text
{
...
"form": {
"key2": "value2",
"key1": "value1"
},
...
}
Ale czasami chcesz wysłać dane które nie są form-encoded. Jeśli przekażesz string zamiast dict, dane będą wysłane prosto to serwera.
Na przykład, GitHub API v3 akceptuje dane POST/PATCH zakodowane w JSON:
>>> import json
>>> url = 'https://api.github.com/some/endpoint'
>>> payload = {'some': 'data'}
>>> r = requests.post(url, data=json.dumps(payload))
POST — plik zakodowany Multipart¶
Requests sprawia, że dodawanie plików zakodowanych Multipart jest proste:
>>> url = 'http://httpbin.org/post'
>>> files = {'file': open('report.xls', 'rb')}
>>> r = requests.post(url, files=files)
>>> r.text
{
...
"files": {
"file": "<censored...binary...data>"
},
...
}
Możesz jawnie ustawić nazwę pliku:
>>> url = 'http://httpbin.org/post'
>>> files = {'file': ('report.xls', open('report.xls', 'rb'))}
>>> r = requests.post(url, files=files)
>>> r.text
{
...
"files": {
"file": "<censored...binary...data>"
},
...
}
Jeśli chcesz, możesz wysłać ciągi znaków, które będą otrzymane jako pliki:
>>> url = 'http://httpbin.org/post'
>>> files = {'file': ('report.csv', 'some,data,to,send\nanother,row,to,send\n')}
>>> r = requests.post(url, files=files)
>>> r.text
{
...
"files": {
"file": "some,data,to,send\\nanother,row,to,send\\n"
},
...
}
Kody odpowiedzi¶
Możemy sprawdzić kod statusu odpowiedzi:
>>> r = requests.get('http://httpbin.org/get')
>>> r.status_code
200
Requests ma też wbudowany obiekt sprawdzania kodów dla łatwej referencji:
>>> r.status_code == requests.codes.ok
True
Jeśli wykonaliśmy złe żądanie (odpowiedź 4XX błąd klienta lub 5XX błąd
serwera), możemy podnieść wyjątek używając Response.raise_for_status():
>>> bad_r = requests.get('http://httpbin.org/status/404')
>>> bad_r.status_code
404
>>> bad_r.raise_for_status()
Traceback (most recent call last):
File "requests/models.py", line 832, in raise_for_status
raise http_error
requests.exceptions.HTTPError: 404 Client Error
Ale, ponieważ status_code dla r wynosił 200, raise_for_status()
wykonuje:
>>> r.raise_for_status()
None
Wszystko jest dobrze.
Nagłówki odpowiedzi¶
Możemy przejrzeć nagłówki odpowiedzi serwera przy użyciu słownika Pythona:
>>> r.headers
{
'content-encoding': 'gzip',
'transfer-encoding': 'chunked',
'connection': 'close',
'server': 'nginx/1.0.4',
'x-runtime': '148ms',
'etag': '"e1ca502697e5c9317743dc078f67693f"',
'content-type': 'application/json'
}
Ten słownik jest specjalny: jest on stworzony tylko dla nagłówków HTTP. Zgodnie z RFC 2616, wielkość liter nie ma znaczenia w nagłówkach HTTP.
Więc możemy uzyskać dostęp do nagłówków używając dowolnej wielkości liter:
>>> r.headers['Content-Type']
'application/json'
>>> r.headers.get('content-type')
'application/json'
Ciasteczka (cookies)¶
Jeśli odpowiedź zawiera jakieś ciasteczka, możesz szybko uzyskać dostęp do nich:
>>> url = 'http://example.com/some/cookie/setting/url'
>>> r = requests.get(url)
>>> r.cookies['example_cookie_name']
'example_cookie_value'
Aby wysłać własne ciasteczka do serwera, możemy użyć parametru cookies:
>>> url = 'http://httpbin.org/cookies'
>>> cookies = dict(cookies_are='working')
>>> r = requests.get(url, cookies=cookies)
>>> r.text
'{"cookies": {"cookies_are": "working"}}'
Przekierowania i historia¶
Requests automatycznie przekieruje żądania przy użyciu GET i OPTIONS.
GitHub przekierowuje wszystkie żądania HTTP na HTTPS. Możemy użyć metody
history obiektu Response do śledzenia przekierowań. Zobaczmy, co robi
GitHub:
>>> r = requests.get('http://github.com')
>>> r.url
'https://github.com/'
>>> r.status_code
200
>>> r.history
[<Response [301]>]
Lista Response.history zawiera obiekty Request stworzone w
celu zakończenia żądania. Lista jest posortowana od najstarzego do najnowszego
żądania.
Jeśli używasz GET lub OPTIONS, możesz zablokować obsługę przekierowań przy
użyciu parametru allow_redirects:
>>> r = requests.get('http://github.com', allow_redirects=False)
>>> r.status_code
301
>>> r.history
[]
Jeśli używasz POST, PUT, PATCH, DELETE lub HEAD, możesz też włączyć automatyczne przekierowania:
>>> r = requests.post('http://github.com', allow_redirects=True)
>>> r.url
'https://github.com/'
>>> r.history
[<Response [301]>]
Timeouty (przekroczenia limitu czasu żądania)¶
Możesz przerwać czekanie na odpowiedź przez Requests po danej liczbie sekund
przy użyciu parametru timeout:
>>> requests.get('http://github.com', timeout=0.001)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
requests.exceptions.Timeout: HTTPConnectionPool(host='github.com', port=80): Request timed out. (timeout=0.001)
Note:
timeout wpływa tylko na połączenie, nie na pobieranie odpowiedzi.
Błędy i wyjątki¶
W razie problemu z siecią (np. nieudane żądanie do DNS, odmowa połączenia
itd.), Requests podniesie wyjątek ConnectionError.
W razie rzadkiej nieprawidłowej odpowiedzi HTTP, Requests podniesie wyjątek
HTTPError.
Jeśli żądanie osiągnie timeout, wyjątek Timeout jest podnoszony.
Jeśli żądanie przekroczy skonfigurowany limit maksymalnych przekierowań, wyjątek
TooManyRedirects jest podnoszony.
Wszystkie wyjątki podnoszone przez Requests dziedziczą z
requests.exceptions.RequestException.
Gotowy na więcej? Sprawdź sekcję zaawansowaną.