# Python'da web sayfasını Markdown'a dönüştürme

> Web sayfalarını Python'da Markdown'a dönüştürün: requests, async httpx ve başlıklara göre RAG parçalama. $0,07/1K sayfa itibarıyla, KYC olmadan.

- URL: https://webreaderapi.com/tr/docs/python/
- Son güncelleme: 2026-10-22
- Yayıncı: WebReaderAPI (https://webreaderapi.com)

Çoğu Python projesini kapsayan dört tarif: requests ile tek sayfa okuma, httpx ile birçok sayfayı eşzamanlı okuma, bir listeyi toplu işe verme ve Markdown'ı bir vektör deposu için parçalara ayırma.

**Hızlı yanıt — Python'da bir web sayfasını Markdown'a nasıl dönüştürürüm?**

**WebReaderAPI** çağrısını `requests.get("https://webreaderapi.com/api/v1/read", params={"url": ...})` ve anahtarınızla `Authorization` header'ında yapın; JSON yanıtı sayfanın ana içeriğini `markdown` içinde tutar. Birçok sayfa için, semaphore veya toplu iş ile `httpx.AsyncClient` kullanın. Bir sayfa 1 kredi; Ekim 2026 itibarıyla $0,07/1K sayfa itibarıyla. KYC yok; kripto ile ödeme.

## Ne kurulu olmalı?

Python 3.9 veya üzeri ve bir HTTP istemcisi. Bir seferde bir sayfa okuyan betikler için `requests` yeterlidir; `httpx` birçok sayfayı paralel okumak için async desteği ekler. Bizim hiçbir paketimiz gerekmez: API düz HTTPS ve JSON'dur.

Anahtarınızı koddan uzak tutun. Aşağıdaki her örnekte olduğu gibi `WEBREADER_API_KEY` environment variable'ından okuyun ve her projeye kendi anahtarını verin, böylece birini diğerlerine dokunmadan iptal edebilirsiniz.

*Kurulum*

```bash
pip install requests httpx
export WEBREADER_API_KEY="your-key"
```

## requests ile tek sayfa nasıl okurum?

`url` ve tüm seçenekleri sorgu parametreleri olarak gönderin, HTTP hatasında hata fırlatın ve ihtiyacınız olan alanları okuyun. Örnek ana içeriği tutar, bir model için 20.000 karakterde sınırlar ve çağrının ne kadara mal olduğunu yazdırır.

*requests: tek sayfa*

```python
import os

import requests

API = "https://webreaderapi.com/api/v1/read"
HEADERS = {"Authorization": "Bearer " + os.environ["WEBREADER_API_KEY"]}


def read(url, **options):
    resp = requests.get(API, headers=HEADERS, params={"url": url, **options}, timeout=75)
    if resp.status_code != 200:
        error = resp.json()["error"]
        raise RuntimeError(error["code"] + ": " + error["message"])
    return resp.json()


page = read("https://example.com/docs/getting-started", max_chars=20000)
print(page["title"], page["word_count"], "words", page["credits_used"], "credit(s)")
print(page["markdown"][:500])

```

## httpx ile birçok sayfayı aynı anda nasıl okurum?

Tek bir `httpx.AsyncClient` ve eşzamanlılık sınırınızda veya altında ayarlanmış bir `asyncio.Semaphore` kullanın. Her hesabın aynı anda okuyabileceği sayfa sayısına bir limit vardır; paneliniz bunu gösterir ve destek ekibi bunu yükseltebilir. Bir sayfadan gelen hatalar diğerlerini durdurmamalı, bu yüzden örnek hata fırlatmak yerine onları sonuçların yanında toplar.

Sınırı aşarsanız API `429 concurrency_limit` yanıtı verir; hiçbir ücret alınmaz ama sayfa okunmaz. Semaphore'u sınırın altında tutmak yeniden denemekten daha basittir.

*httpx: aynı anda en fazla 10 sayfa*

```python
import asyncio
import os

import httpx

API = "https://webreaderapi.com/api/v1/read"
HEADERS = {"Authorization": "Bearer " + os.environ["WEBREADER_API_KEY"]}


async def read_one(client, sem, url):
    async with sem:
        resp = await client.get(API, params={"url": url, "max_chars": 50000})
    body = resp.json()
    if resp.status_code == 200:
        return url, body, None
    return url, None, body["error"]["code"]


async def read_many(urls, limit=10):
    sem = asyncio.Semaphore(limit)
    async with httpx.AsyncClient(headers=HEADERS, timeout=75) as client:
        return await asyncio.gather(*(read_one(client, sem, u) for u in urls))


if __name__ == "__main__":
    urls = [f"https://example.com/blog/post-{n}" for n in range(1, 21)]
    for url, page, error in asyncio.run(read_many(urls)):
        print(url, "->", error or page["title"])

```

## Bunun yerine ne zaman batch job kullanmalıyım?

En fazla 100 URL'den oluşan bir listeniz varsa ve her sayfaya hazır olduğu anda ihtiyaç duymuyorsanız. Bir batch job bizim tarafımızda çalışır; böylece scriptiniz açık bağlantı tutmaz ve retry mantığı yürütmez. `POST https://webreaderapi.com/api/v1/batch` ile başlatın, ardından [batch ve crawl sayfasında](https://webreaderapi.com/tr/docs/crawl/) gösterilen cursor döngüsüyle job'dan sonuçları toplayın.

Tüm bir site için bunun yerine bir crawl başlatın ve sitemap ile bağlantıları takip etmesine izin verin; aynı sayfada her sayfa için bir `.md` dosyası yazan eksiksiz bir döngü var.

*Bir batch işi başlatın*

```python
import os

import requests

urls = [f"https://example.com/changelog/{year}" for year in range(2020, 2027)]
resp = requests.post(
    "https://webreaderapi.com/api/v1/batch",
    headers={"Authorization": "Bearer " + os.environ["WEBREADER_API_KEY"]},
    json={"urls": urls, "options": {"format": "markdown", "main_content": True}},
    timeout=30,
)
resp.raise_for_status()
print("job:", resp.json()["job_id"])

```

## Markdown'ı RAG için nasıl parçalara bölerim?

Önce başlıklara göre, sonra boyuta göre bölün. Başlıklar konuların nerede değiştiğini gösterir, bu yüzden bir başlıkta başlayan parçanın bir retriever tarafından eşleştirilmesi daha kolaydır. Sayfa başlığını ve başlık yolunu her parçanın metadata'sında tutun: bunlar modelin doğru bölümü alıntılamasına yardımcı olur.

Aşağıdaki fonksiyon ek bir kütüphane gerektirmez. `#` ile `###` başlık arasında keser, sonra karakter bütçesinin altında kalmak için uzun bölümleri boş satırlardan böler. `final_url` değerini her parçayla birlikte saklayın, böylece aynı sayfaya giden iki adres kopya oluşturmaz.

*Markdown'ı başlıklara göre parçalama*

```python
import re


def chunk_markdown(page, max_chars=2000):
    """Split a /read response into chunks with a heading path and the source URL."""
    chunks, path, buf = [], [], []

    def flush():
        text = "\n".join(buf).strip()
        while text:
            part = text[:max_chars]
            cut = part.rfind("\n\n")
            if len(text) > max_chars and cut > max_chars // 2:
                part = part[:cut]
            chunks.append({"text": part.strip(), "section": " > ".join(path), "title": page.get("title"), "source": page["final_url"]})
            text = text[len(part):].strip()
        buf.clear()

    for line in page["markdown"].splitlines():
        m = re.match(r"^(#{1,3}) (.+)", line)
        if m:
            flush()
            level = len(m.group(1))
            path[:] = path[: level - 1] + [m.group(2).strip()]
        buf.append(line)
    flush()
    return chunks

```

## Bir Python job'u ne kadar maliyetlidir?

İstekleri değil, sayfaları sayın. 1 kredi = tarayıcı olmadan 1 sayfa okuma; sayfa JavaScript render etmek için tarayıcı gerektiriyorsa 2 kredi. Başarısız olan veya bir sitenin robots.txt'inin reddettiği istek için ücret alınmaz. 2.000 dokümantasyon sayfasını tarayıcı olmadan okumak yaklaşık 2.000 kredi kullanır; bunu 10.000 sayfa ($3,75) beş katıyla karşılar. Ön ödemeli kreditler asla süresi dolmaz: kullanılmayan sayfalar siz kullanana kadar hesabınızda kalır, bu yüzden ayda bir çalışan bir pipeline yalnızca okuduğu kadarını kullanır.

## Python: sık sorulan sorular

### Resmi bir Python paketi var mı?

Hayır. Bu sayfadaki kod ihtiyacınız olan her şey: WebReaderAPI sade bir HTTPS API'sidir ve `requests` veya `httpx` doğrudan bununla konuşur.

### robots.txt'in reddettiği bir sayfayı nasıl ele alırım?

Hata kodunu kontrol edin. `blocked_by_robots` ve `target_refused` kesindir ve ücretsizdir; bunları kaydedin ve devam edin. [Hatalar sayfasında](https://webreaderapi.com/tr/docs/errors/) yalnızca değişebilecek kodları yeniden deneyen bir retry yardımcısı var.

### API'yi bir Jupyter notebook'tan kullanabilir miyim?

Evet. `requests` tarifi olduğu gibi çalışır. Bir notebook'ta `await read_many(urls)`, `asyncio.run` yerine geçer, çünkü notebook zaten bir event loop çalıştırır.

### İstemcim hangi timeout değerini kullanmalı?

API'nin kendi değerinden biraz daha fazlasını: varsayılan 30 saniye, maksimum 60 saniyedir; bu yüzden istemci tarafında 75 saniye, yavaş bir site ve yanıt için pay bırakır.

---

WebReaderAPI: WebReaderAPI, AI ajanları için bir web reader API'sidir; herkese açık herhangi bir web sayfasını temiz Markdown'a dönüştürür ve kimlik yüklemeden kripto ile ödenir. $0,07/1K sayfa başlangıçlı ön ödemeli kreditler asla süresi dolmaz ve robots.txt'e uyulur. KYC yok — kimlik yok, selfie yok, belge yok. Kripto ile ödeme yapın.
