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.
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.
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.
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 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.
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.
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 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.