Hızlı yanıt
Python'dan SERP API'sini nasıl çağırırım?
requests veya httpx ile https://serpcrypto.com/api/v1/search adresine bir GET isteği gönderin, anahtarınızı Authorization: Bearer header'ına ve sorguyu params parametresine koyun, ardından response.json() alanını okuyun. SerpCrypto her başarılı arama için 1 kredi alır, $0,30/1K arama'den başlar ve başarısız çağrıların yeniden denenmesi ücretsizdir. Kripto ile ödeme, KYC yok. Aşağıdaki kod yalnızca requests veya httpx gerektirir.
Bir bakışta Python kurulumu
| Kurulum | pip install requests veya pip install httpx |
|---|---|
| Anahtar | Ortam değişkeni SERPCRYPTO_API_KEY |
| Header | Authorization: Bearer <key> |
| Zaman aşımı | 60 ila 90 saniye: arama canlı çalışır |
| Yeniden deneme | Yalnızca 429, 502 ve 504, geri çekilmeli; hatalar ücretsizdir |
| Paralel aramalar | GET /credits'den itibaren concurrency_limit'e kadar |
Yeniden kullanılabilir bir Python istemcisini nasıl kurarım?
Anahtarı header'larında ve üç geçici hata için bir yeniden deneme politikası olan tek bir requests.Session oluşturun. Bir session bağlantıları yeniden kullanır, böylece bir arama döngüsü TLS el sıkışmalarına daha az zaman harcar. Dosyayı serp_client.py olarak kaydedin; sonraki örnekler onu import eder.
urllib3'ten Retry her yeni denemeden önce daha uzun bekler ve bir Retry-After header'ı gönderilirse ona uyar. Düzeltme gerektiren, ikinci bir deneme gerektirmeyen 400, 401 veya 402 hatalarını asla yeniden denemez.
"""serp_client.py: a small, reusable client for the SerpCrypto SERP API (requests)."""
import os
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
API_URL = "https://serpcrypto.com/api/v1/search"
CREDITS_URL = "https://serpcrypto.com/api/v1/credits"
def make_session():
session = requests.Session()
session.headers["Authorization"] = "Bearer " + os.environ["SERPCRYPTO_API_KEY"]
retry = Retry(
total=4,
backoff_factor=1.0, # waits about 1 s, 2 s, 4 s between attempts
status_forcelist=(429, 502, 504),
allowed_methods=("GET",),
respect_retry_after_header=True,
)
session.mount("https://", HTTPAdapter(max_retries=retry))
return session
SESSION = make_session()
def search(q, **params):
"""Run one search (1 credit if it succeeds) and return the parsed JSON."""
r = SESSION.get(API_URL, params={"q": q, **params}, timeout=90)
r.raise_for_status()
return r.json()
def credits():
"""Free: credits left, used today and the concurrency limit."""
r = SESSION.get(CREDITS_URL, timeout=30)
r.raise_for_status()
return r.json()
if __name__ == "__main__":
data = search("project management software", gl="us", hl="en")
for item in data.get("organic_results", []):
print(item["position"], item["link"])
print(credits())10'dan fazla sonucu nasıl toplarım?
Sonraki sayfaları tek tek isteyin. Google'ın Eylül 2025'te num=100 değerini dikkate almayı bırakmasından bu yana sunduğu gibi sayfa başına yaklaşık 10 organik sonuç; her ek sayfa bir kredi daha. pagination.next_page eksik olur olmaz durun: alınacak başka bir şey yoktur ve kredileri korursunuz.
Çoğu sıralama takibi işi için ilk sayfa veya ilk üç sayfa yeterlidir, çünkü tıklamalar orada yoğunlaşır. Bir anahtar kelime için otuz sonuç üç krediye mal olur.
from serp_client import search
def top_results(q, pages=3, **params):
"""Collect organic results over several pages: each page is 1 credit."""
rows = []
for page in range(1, pages + 1):
data = search(q, page=page, **params)
for item in data.get("organic_results", []):
rows.append({"page": page, "position": item["position"], "title": item["title"], "link": item["link"]})
if not data.get("pagination", {}).get("next_page"):
break # no further page: stop early and save credits
return rows
rows = top_results("crm for small business", pages=3, gl="gb", hl="en")
print(len(rows), "results")Birçok aramayı paralel olarak nasıl çalıştırırım?
Hesabınızın sınırına göre boyutlandırılmış bir asyncio.Semaphore ile httpx.AsyncClient kullanın. Script, ücretsiz krediler endpoint'inden concurrency_limit okur, böylece destek ekibiniz sınırınızı yükselttiğinde uyum sağlar. Sınırın üzerindeki aramalar zaten 429 alırdı; semaphore bu denemeleri boşa harcamayı önler.
Her görev geçici hataları artan bir beklemeyle yeniden dener ve dört başarısızlıktan sonra None döndürür, böylece inatçı bir sorgu partiyi asla engellemez.
"""Run many searches in parallel without exceeding the account's concurrency limit."""
import asyncio
import os
import httpx
API_URL = "https://serpcrypto.com/api/v1/search"
CREDITS_URL = "https://serpcrypto.com/api/v1/credits"
HEADERS = {"Authorization": "Bearer " + os.environ["SERPCRYPTO_API_KEY"]}
async def search_one(client, gate, q):
async with gate: # at most N searches at the same time
for attempt in range(4):
r = await client.get(API_URL, params={"q": q, "gl": "us", "hl": "en"})
if r.status_code in (429, 502, 504):
await asyncio.sleep(2 ** attempt)
continue
r.raise_for_status()
return q, r.json()
return q, None
async def main(queries):
async with httpx.AsyncClient(headers=HEADERS, timeout=90) as client:
limits = (await client.get(CREDITS_URL)).json()
gate = asyncio.Semaphore(limits["concurrency_limit"])
results = await asyncio.gather(*(search_one(client, gate, q) for q in queries))
for q, data in results:
first = (data or {}).get("organic_results", [{}])[0].get("link")
print(f"{q!r}: {first}")
asyncio.run(main(["best vpn router", "home espresso machine", "4k monitor for coding"]))Günlük sıralamaları bir CSV dosyasına nasıl kaydederim?
Her sonuç için bir satır ekleyin: gün, anahtar kelime, pozisyon, bağlantı ve API'nin uyguladığı ayarlar. gl ve device değerlerini kendi değişkenlerinizden değil search_parameters'den okumak, dosyanın gerçekte kullanılanı kaydetmesi anlamına gelir.
Scripti cron veya Windows Task Scheduler ile günde bir kez çalıştırın. Mobilde üç anahtar kelime günde üç krediye, ayda yaklaşık 90 krediye mal olur.
import csv
from datetime import date
from serp_client import search
KEYWORDS = ["standing desk", "ergonomic chair", "monitor arm"]
FIELDS = ["day", "keyword", "position", "title", "link", "gl", "device"]
with open("rankings.csv", "a", newline="", encoding="utf-8") as fh:
writer = csv.DictWriter(fh, fieldnames=FIELDS)
if fh.tell() == 0:
writer.writeheader()
for kw in KEYWORDS:
data = search(kw, gl="gb", hl="en", device="mobile")
applied = data["search_parameters"]
for item in data.get("organic_results", []):
writer.writerow({
"day": date.today().isoformat(),
"keyword": kw,
"position": item["position"],
"title": item["title"],
"link": item["link"],
"gl": applied["gl"],
"device": applied["device"],
})Hangi Python HTTP istemcisini kullanmalıyım?
Betikler ve cron job'lar için requests kullanın: basittir ve retry adaptörü olgundur. Bir web uygulaması, ajan ya da yüzlerce anahtar kelimelik toplu iş gibi asenkron kod gerektiğinde httpx kullanın. İkisi de aynı isteği gönderir ve aynı JSON'u alır; API hangisini seçtiğinizi umursamaz.
Her iki kütüphanede de çok kısa timeout değerlerinden kaçının. Beş saniye sonra vazgeçen bir istemci, hâlâ çalışan bir aramayı yeniden gönderebilir ve ikisi için de ödeme yapabilir.
Betiğim ne kadara mal olur?
Sonuçları değil, aramaları sayın: başarılı olan bir çağrı bir kredidir. Her gün 30 gün boyunca, her biri tek sayfa olan 500 anahtar kelimelik bir iş, 15.000 aramadır. 25.000 arama pakette ($18,75) bu rahatça sığar ve Ön ödemeli arama kredileri hiçbir zaman sona ermez: kullanılmayan aramalar siz kullanana kadar hesabınızda kalır.
Bakiyeyi yukarıdaki credits() helper'ı ile koddan kontrol edin; hiçbir maliyeti yoktur.
Python soruları
PyPI'da SerpCrypto paketi var mı?
Hayır. Örnekler HTTPS endpoint'ini requests veya httpx ile çağırır; bunlar yaygın kullanılan iki kütüphanedir, dolayısıyla kuracağınız ya da güncelleyeceğiniz bize ait bir şey yoktur. Yukarıdaki client yaklaşık 40 satırdır ve size aittir.
Bu kod hangi Python sürümlerini destekliyor?
Python 3.9 ve sonrası. Asenkron örnek, Python 3.7'den beri mevcut olan asyncio.run kullanır; geri kalanı ise yalnızca standart kütüphane ile requests veya httpx kullanır.
API'yi Jupyter notebook'tan kullanabilir miyim?
Evet. Jupyter'i başlatmadan önce SERPCRYPTO_API_KEY ayarlayın ya da anahtarı notebook içinde getpass ile okuyun, böylece kaydedilmiş bir hücreye girmez. Notebook'ta asyncio.run(main(...)) yerine await main(...) kullanın.
Sonuçları nasıl pandas DataFrame'e dönüştürürüm?
Sonuç sözlüklerinin listesini pandas.DataFrame(data["organic_results"]) fonksiyonuna verin. Her field bir sütun olur; date gibi eksik opsiyonel field'lar boş hücrelere dönüşür.