Menu

Python HTTP İstekleri: requests Kütüphanesiyle (GET, POST, JSON)

Python'da requests kütüphanesi ile nasıl HTTP isteği yapılır — GET, POST, sorgu parametreleri, başlıklar, JSON gövdeleri ve hata yönetimi.

Birkaç Satırda İnternetten Veri Çekmek

Çoğu gerçek Python programı er ya da geç ağ üzerinden bir şeyle konuşmak zorunda kalır — bir REST API, bir hava durumu servisi, bir GitHub endpoint'i, bir indirme. Standart kütüphane bunu yapabilir (urllib üzerinden) ama Python dünyasındaki fiili araç requests adlı üçüncü parti bir kütüphanedir. API'si o kadar daha dostça ki tek bir pip install'a değer.

pip install requests

Zaten bir sanal ortamda çalışmıyorsan önce bir tane kur — bu, kurulumu projenle sınırlı tutar.

İlk GET İsteği

main.py
Output
Click Run to see the output here.

Üç satır: get çağır, status kodunu kontrol et, gövdeye bak. response.text, yanıt gövdesini string olarak verir. Tam JSON uzun olduğu için burada kırpılmış.

Göz aşinalığı kazanmaya değer status kodları:

  • 200 — Tamam, her şey yolunda.
  • 201 — Oluşturuldu (yaygın POST yanıtı).
  • 301 / 302 — yönlendirmeler; requests varsayılan olarak otomatik takip eder.
  • 400 — kötü istek; gönderdiklerinde bir şey yanlış.
  • 401 / 403 — kimlik doğrulanmamış / yetkilendirilmemiş.
  • 404 — kaynak yok.
  • 429 — hız sınırı aşıldı; yavaşla.
  • 500 — sunucu hatası.

JSON Yanıtı Ayrıştırmak

Endpoint JSON döndürdüğünde yanıt üzerinde .json() çağır — gövdeyi ayrıştırır ve sana bir dict (ya da list) verir:

main.py
Output
Click Run to see the output here.

Arka planda .json(), json.loads(response.text) ile aynıdır — sadece yaygın durum için bir kısayol.

Sorgu Parametreleri Göndermek

URL'ye manuel olarak ?key=value&... yapıştırma. params='a bir dict geç:

main.py
Output
Click Run to see the output here.

requests senin için URL kodlamasını yönetir — boşluklar, özel karakterler, Unicode her şey güvenle çalışır.

Giden asıl URL, response.url'de mevcut; hata ayıklamada kullanışlı.

JSON Gövdeli POST İstekleri

Veri göndermek için — kaynak oluşturma, form gönderme, değiştirici endpoint'leri çağırma — requests.post kullan:

import requests

payload = {
    "title": "Docs update",
    "body": "Added HTTP requests page.",
    "labels": ["docs"],
}

response = requests.post(
    "https://api.example.com/issues",
    json=payload,
    headers={"Authorization": "Bearer YOUR_TOKEN"},
)

print(response.status_code)
print(response.json())

json= argümanı iki şey yapar: payload'ı JSON'a serileştirir ve Content-Type: application/json ayarlar. İkisini de elle data=json.dumps(payload) ve açık bir başlıkla yapabilirsin ama json= deyimsel kısayoldur.

Form-encoded veri için (klasik bir HTML formunun gönderdiği tür), data= kullan:

requests.post("https://example.com/login", data={"user": "rosa", "password": "..."})

Başlıklar

Her türlü özel başlığı dict olarak geç:

import requests

response = requests.get(
    "https://api.example.com/profile",
    headers={
        "Authorization": "Bearer abc123",
        "User-Agent": "my-tool/1.0",
    },
)

Çoğu API, kimlik doğrulama için bir Authorization başlığı ister. Tam şema (Bearer, Basic, Token) dokümanlarında yazar.

Timeout'lar İsteğe Bağlı Değil

Varsayılan olarak requests yanıt için sonsuza dek bekler. Gerçek bir programda bu, kararsız bir sunucuyu asılı kalmış bir script'e çevirir. Her zaman bir timeout geç:

import requests

try:
    response = requests.get("https://api.example.com/slow", timeout=5)
except requests.Timeout:
    print("Server took too long.")

Sayı saniye cinsindendir. timeout=5, "5 saniye içinde yanıt yoksa vazgeç" demektir. Daha fazla kontrol için bir tuple (connect_timeout, read_timeout) geçebilirsin.

Hata Yönetimi

İki tür sorun olabilir:

  1. HTTP düzeyinde hatalar (4xx, 5xx) — sunucu yanıtladı ama yanıt bir hata. Sana response.status_code söyler.
  2. Ağ düzeyinde sorunlar — timeout'lar, DNS hataları, erişilemeyen sunucular. Bunlar istisna fırlatır.

Deyimsel kalıp ikisini birleştirir:

main.py
Output
Click Run to see the output here.

raise_for_status(), 2xx yanıtlar için hiçbir şey yapmaz; aksi halde istisna fırlatır. RequestException, requests'ın fırlattığı her hatanın temel sınıfıdır — "bu endpoint'le konuşurken yanlış giden her şey" için tek bir yakalama.

Dosya İndirmek

Büyük ikili indirmeler için yanıtı akış olarak işle ki bellekte oturmasın:

import requests

url = "https://example.com/large.zip"

with requests.get(url, stream=True, timeout=30) as r:
    r.raise_for_status()
    with open("large.zip", "wb") as f:
        for chunk in r.iter_content(chunk_size=8192):
            f.write(chunk)

stream=True, requests'a gövdeyi önceden yüklememesini söyler. iter_content(chunk_size=...), gövdeyi parça parça verir; sen de doğrudan diske yazarsın.

Oturumlar: Bağlantıları ve Varsayılanları Tekrar Kullanmak

Aynı servise birkaç istek yapacaksan bir Session kullan. Alttaki TCP bağlantısını tekrar kullanır (daha hızlı) ve varsayılanları bir kez ayarlamana olanak tanır:

import requests

session = requests.Session()
session.headers.update({"Authorization": "Bearer abc123"})

# Every request through this session carries the header.
a = session.get("https://api.example.com/users/1")
b = session.get("https://api.example.com/users/2")
c = session.post("https://api.example.com/users", json={"name": "Rosa"})

Aynı API'ye onlarca kez vuran script'ler için oturum anlamlı bir hızlanmadır.

Gerçekçi Bir Örnek: Küçük Bir GitHub İstemcisi

Bir repo'nun son sürümünü çekmek:

import requests

def latest_release(owner, repo):
    url = f"https://api.github.com/repos/{owner}/{repo}/releases/latest"
    response = requests.get(url, timeout=10)
    response.raise_for_status()
    data = response.json()
    return {
        "tag": data["tag_name"],
        "name": data["name"],
        "published": data["published_at"],
        "url": data["html_url"],
    }

release = latest_release("python", "cpython")
print(release)

On beş satırın altında: URL'yi kur, iste, hataları kontrol et, ilgilendiğin alanları çıkar. Yazacağın çoğu API istemcisi bu şekildedir.

urllib Ne Olacak?

Standart kütüphanedeki urllib.request, requests'ın yapabildiği her şeyi yapabilir — daha fazla satırla ve daha kötü ergonomiyle. Kesinlikle bağımlılık ekleyemiyorsan orada:

import json
import urllib.request

with urllib.request.urlopen("https://api.github.com/repos/python/cpython") as r:
    data = json.loads(r.read().decode("utf-8"))

print(data["name"])

Hızlı bir script'in ötesinde herhangi bir şey için requests (ya da async gerekirse httpx) kuruluma değer.

Birkaç Alışkanlık

  • Her zaman bir timeout ayarla. İstisnasız.
  • Başarı bekleyen script'lerde raise_for_status() kullan — kötü bir yanıtı yüksek sesli bir istisnaya dönüştürür.
  • Elle kurulmuş string'ler yerine params= ve json='a dict geç.
  • Aynı API'ye çok vurduğunda ilgili çağrıları bir Session'a sar.
  • Hata ayıklarken response.status_code ve response.text'i logla — gövde genelde sunucunun neden takıldığını söyler.

Sırada: Tarihler ve Saatler

Takımında requests ile artık herhangi bir modern web API'siyle konuşabilir, dosya indirebilir ve servisler arasında küçük entegrasyonlar kurabilirsin. Bundan önceki JSON ve CSV sayfalarıyla birleşince, artık tam "veri çek, oku, onunla bir şey yap, geri yaz" döngüsüne sahipsin — çok sayıda gerçek Python script'inin şekli. Ancak bu verinin çoğunda bir zaman damgası var ve bir sonraki sayfa, Python'un tarihleri, saatleri ve kaçınmaya değer saat dilimi tuzaklarını nasıl temsil ettiğini anlatıyor.

Sıkça Sorulan Sorular

Python'da nasıl bir HTTP isteği yaparım?

pip install requests ile requests kütüphanesini kur, sonra GET için requests.get(url), POST için requests.post(url, json=...) çağır. Yanıt nesnesinin .status_code, .text, .json() ve .headers alanları vardır. Örnek: r = requests.get('https://api.example.com/users/1').

requests mı yoksa urllib mi kullanmalıyım?

Elle yazacağın her şey için requests — API'si fazlasıyla dostça. urllib yerleşiktir ve bağımlılık eklemek imkânsızsa iş görür, ama JSON gövdeleri ve oturumlar gibi şeyler için daha fazla kod ister. Prodüksiyonda çoğu takım ayrıca httpx'i (async desteği olan requests-uyumlu bir kütüphane) kullanır.

Python'da POST isteğinde JSON nasıl gönderilir?

requests.post(...)'a json={'key': 'value'} geç. requests dict'i JSON'a serileştirir ve senin için Content-Type: application/json ayarlar. Hem data= hem json= geçme — birini seç.

requests kütüphanesiyle hataları nasıl yönetirim?

response.status_code'u kontrol et (200 başarı anlamına gelir) ya da 4xx/5xx'te istisna fırlatması için response.raise_for_status() çağır. Ağ düzeyindeki sorunlar (timeout, DNS hataları) requests.RequestException'ın alt sınıflarını fırlatır — ikisini birden yakalamak için onu yakala.

Coddy ile kodlamayı öğren

BAŞLA