Python Requests Kütüphanesi

Python Requests Kütüphanesi

requests minimalist bir python modülüdür. Bu modül ile en temel şekilde http/https protokollerine yönelik request/response işlemlerimizi gerçekleştirebiliriz.
Requests modülünü pip ile kurmak için;

1
pip3 install requests

Kaynak koddan kurmak için ise;

1
git clone git://github.com/kennethreitz/requests.git

indirdiğiniz dizine girip python3 setup.py install diyerek kurabilirsiniz.

Everything is request
Artık modülümüzü kullanmaya başlayabiliriz.

1
2
import request
req = requests.get("http://musana.net")

En basit haliyle; musana.net adresine get metoduyla bir istekte bulunduk ve artık elimizde req adında bir nesne mevcut. İstekte bulunduğumuz bağlantıya ait bütün bilgilere req nesnesi üzerinden erişebiliriz.

HTTP metodları ile istek yapmak
GET metodu ile ilgili parametre(ler)ye değer vermek veya POST metodu ile form elemanlarına değer verip göndermek için özellikle sözlük veri tiplerinden yararlanıyoruz. Aşağıdaki kod blogunu inceleyerek verilen parametreye bağlı olarak oluşan url yapısına dikkat ediniz.

1
2
3
4
5
6
7
8
9
10
11
12
13
import requests

req = requests.get("http://musana.net", params={'par':'value'})
print(req.url) #Output: http://musana.net/?par=value

req = requests.get("http://musana.net", params={'par1':'value1', 'par2':'value2'})
print(req.url) #Output: http://musana.net/?par1=value2&par2=value2

req = request.get("http://musana.net", params={'par1':'value1', 'par2':['val1', 'val2', 'val3']})
print(req.url) #Output: http://musana.net/?par1=value1&par2=val1&par2=val2&par2=val3

req = requests.post("http://musana.net", data={'kullanici':'musa', 'meslek':'talebe'})
#Yukarıdaki kod; name attributenün değeri 'kullanici' olan form elemanının value değerini `musa` ve diğer name attributenün değeri 'meslek' olanın value değerini `talebe` olacak şekilde post metodunu kullanarak request gönderecektir.

Diğer HTTP metotlarını kullanarak request göndermek istediğimizde ise değişen tek şey metot isimleridir.

1
2
3
4
5
6
import requests	
# Diğer http metodları ile istek yapmak
req = reqeusts.head("http://musana.net")
req = requests.delete("http://musana.net")
req = requests.option("http://musana.net")
req = requests.head("http://musana.net")

HTTP Başlık Bilgisi Ekleme
İstekte bulunurken HTTP başlık bilgilerini(Referrer, host, cookie, user-agent vs) eklemek isteyebiliriz. Bunun için methodumuza headers parametresini tanımlayacağız ve değerini ise sözlük veri tipini kullanarak {"http-baslık-adı":"baslık-degeri"} şeklinde vereceğiz. Örneğin bir web uygulamasının web sürümünde çıkan captcha, mobil sürümünde çıkmayabilir. Bu durumda kolaylıkla olası bir brute-force saldırısı düzenlenebilir. HTTP başlıklarından user-agent değerini mobil bir telefonun browser bilgilerini ekleyerek captcha’yı bypass edebiliriz.

1
2
import requests
req = requests.post('http://musana.net', headers={'user-agent':'Mozilla/5.0 (Linux; Android 6.0.1; SM-G920V Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.98 Mobile Safari/537.36'}

Yukarıdaki kod musana.net sitesine Samsung Glaxy S6 telefonunun kullanıdğı tarayıcı bilgilerini kullanarak istekte bulunacak ve hedef site gelen user-agent bilgisine göre cevap döndürecektir. Örneğimiz üzerinden gidersek captcha çıkmayacağı anlamına gelir bu. Diğer http header bilgilerini de aynı bu yöntemle istediğiniz şekilde değiştirebilirsiniz.

HTTP Response İşlemleri
İstek yaptığımıza göre artık dönen cevabı nasıl işleyebileceğimize bakalım.

1
2
3
import requests
req = requests.get("http://musana.net", params={'par1':'value1', 'par2':'value2'})
print(req.text) # Dönen cevabı text formatına çevirdik. Artık normal bir string üzerinde yapabileceğiniz tüm işlemleri yapabilirsiniz.

Yaptığımız isteğe karşılık dönen HTTP Response kodunu öğrenmek için ise;

1
2
3
import requests
req = reqeusts.get("http://musana.net")
print(req.status_code) #Output: 200, 404?, 302?, 500? ...

Sunucudan dönen cevabın başlık bilgilerine erişebilmek için ise request nesnemize headers nesne değişkeni üzerinden erişebiliriz. Bu değer bize bütün header response bilgisini sözlük tipinde verecektir. Daha spesifik başlıklara erişmek için sözlük yapısını kullanabiliriz. Örneğin;
req.headers.get("content-type") diyerek içeriğin hangi formatta ve hangi karakter setini kullandığı bilgisine ulaşabiliriz. Erişmeye çalıştığımız başlık değeri yok ise sonuç None dönecektir.

1
2
3
4
5
6
7
8
9
10
import request

req = requests.get("http://musana.net")
print(req.headers)
#Çıktımız:
{'CF-RAY': '307f6aa1408a2bb2-AMS', 'Server': 'cloudflare-nginx', 'X-GitHub-Request-Id': 'ADF53550:23C34:E6E456:5839D4F6', 'Date': 'Sat, 26 Nov 2016 18:31:18 GMT', 'Cache-Control': 'max-age=600', 'Set-Cookie': '__cfduid=d1c34cf17ebe35c3c407a8ca97672e1951480185077; expires=Sun, 26-Nov-17 18:31:17 GMT; path=/; domain=.musana.net; HttpOnly', 'Access-Control-Allow-Origin': '*', 'Content-Encoding': 'gzip', 'Expires': 'Sat, 26 Nov 2016 18:41:18 GMT', 'Content-Type': 'text/html; charset=utf-8', 'Connection': 'keep-alive', 'Transfer-Encoding': 'chunked', 'Last-Modified': 'Fri, 18 Nov 2016 11:31:04 GMT'}

# Sadece istenilen başlık değerine ulaşmak istersek;
print(req.headers.get("content-type")) # Output: text/html; charset=utf-8
print(req.headers.get("content-encoding")) # Output: gzip

Dosya Göndermek
Her zaman string bir ifade göndermeyebiliriz. Karşı sunucuya bir dosya yüklemek isteyebiliriz bunun için ise files parametresini tanımlayıp değerine sözlük veri tipi yardımıyla bir dosya adı veya dosya içeriğini veriyoruz.

1
2
3
import requests
dosya = {"dosyam":open("python.txt", "rb")} #name değeri dosyam olan form elemanını python.txt dosyamıza binary form
req = requests.post("http://musana.net", files=dosya)

Bir string ifadeyi istediğimiz bir dosya formatında göndermek için ise;

1
2
3
import requests
dosya = {"dosyam":("python.txt", "Burası python.txt dosyasına yazılmaktadır.")}
req = requests.post("http://musana.net", files=dosya)

Timeout, SSL, HTTP Basic Auth
Göndereceğimiz isteğin zaman aşım süresini kontrol etmek isteyebileceğimiz durumlar olabilir. Bu durumda timeout parametesine dönecek olan cevabın verdiğimiz zaman değerini aşması durumunda isteğimiz zaman aşımına uğrayacaktır. Meydana gelen ConnectTimeoutError hatasını exception handling ile kontrol edebiliriz.

1
2
3
import requests
req = requests.get('http://github.com', timeout=0.099)
# İstek yapıldıktan sonra 99 milisaniye sonra cevap dönmez ise timeout meydana gelir.

Request göndereceğimiz bağlantının SSL desteği varsa yani HTTPS protokolünü kullanıyorsa bağlanmak istediğimiz zaman requests.exceptions.SSLError hatasını alabiliriz. Bu durumda verify parametresine sertifika yolumuzu belirterek istek gönderebiliriz.

1
2
import requests
requests.get('https://github.com', verify='/sertifikanızın/dizin/adresi')

Ayrıca verify parametresine False değerini vererek doğrulanmış SSL sertifikasını göz ardı edebilirsiniz.

HTTP Basic Authentication kimlik doğrulamasında login olabilmek için ise;

1
2
from requests.auth import HTTPBasicAuth
requests.get('https://api.github.com/user', auth=HTTPBasicAuth('user', 'pass'))

requests modülünü kullanarak yapabileceğimiz en temel işlemler bunlar olmakla beraber daha fazlası için resmi dökümantasyonu inceleyebilirsiniz.

Sağlıcakla kalınız.

Comments