# SERP API in Python: requests, httpx und asyncio

> Nutzen Sie die SerpCrypto SERP API in Python: ein requests-Client mit Retries, async httpx mit Concurrency-Limit, Pagination und CSV-Export. Getesteter Code.

- URL: https://serpcrypto.com/de/docs/python/
- Zuletzt aktualisiert: 2026-10-22
- Herausgeber: SerpCrypto (https://serpcrypto.com)

Ein wiederverwendbarer Client mit Retries, eine Pagination-Schleife, die stoppt, wenn die Ergebnisse enden, asynchrone Suchanfragen begrenzt auf Ihr Concurrency-Limit und eine tägliche CSV für Rankings. Copy-paste-Code, syntaxgeprüft, ohne dass Sie ein Paket von uns installieren müssen.

**Kurze Antwort — Wie rufe ich eine SERP API aus Python auf?**

Senden Sie eine GET-Anfrage an `https://serpcrypto.com/api/v1/search` mit `requests` oder `httpx`, Ihren Schlüssel im Header `Authorization: Bearer` und die Suchanfrage in `params`, und lesen Sie dann `response.json()`. **SerpCrypto** berechnet 1 Credit pro erfolgreicher Suche, ab 0,30 $/1K Suchanfragen, und Retries fehlgeschlagener Aufrufe sind kostenlos. Mit Krypto bezahlen, ohne KYC. Der folgende Code benötigt nur `requests` oder `httpx`.

## Python-Setup auf einen Blick

| Attribut | Wert |
| --- | --- |
| Installation | `pip install requests` oder `pip install httpx` |
| Schlüssel | Umgebungsvariable `SERPCRYPTO_API_KEY` |
| Header | `Authorization: Bearer <key>` |
| Timeout | 60 bis 90 Sekunden: eine Suche läuft live |
| Retry | Nur 429, 502 und 504, mit Backoff; Fehler sind kostenlos |
| Parallele Suchen | Bis zu `concurrency_limit` ab `GET /credits` |

## Wie richte ich einen wiederverwendbaren Python-Client ein?

Erstellen Sie einen `requests.Session` mit dem Schlüssel in den Headers und einer Retry-Policy für die drei temporären Fehler. Eine Session verwendet Verbindungen wieder, sodass eine Schleife von Suchanfragen weniger Zeit für TLS-Handshakes aufwendet. Speichern Sie die Datei als `serp_client.py`; die nächsten Beispiele importieren sie.

`Retry` aus urllib3 wartet vor jedem neuen Versuch länger und beachtet einen `Retry-After`-Header, falls einer gesendet wird. Es wiederholt nie `400`, `401` oder `402`, die eine Korrektur brauchen, keinen zweiten Versuch.

*serp_client.py*

```python
"""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())
```

## Wie sammle ich mehr als 10 Ergebnisse?

Fragen Sie die nächsten Seiten einzeln ab. Etwa 10 organische Ergebnisse pro Seite, so wie Google sie liefert, seit num=100 im September 2025 nicht mehr berücksichtigt wird; jede weitere Seite kostet einen weiteren Credit. Stoppen Sie, sobald `pagination.next_page` fehlt: Es gibt nichts mehr abzurufen, und Sie behalten die Credits.

Für die meiste Rank-Tracking-Arbeit reichen die erste Seite oder die ersten drei Seiten, weil sich Klicks dort konzentrieren. Dreißig Ergebnisse für ein Keyword kosten drei Credits.

*Pagination: bis zu drei Seiten, früher Stopp*

```python
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")
```

## Wie führe ich viele Suchanfragen parallel aus?

Nutzen Sie `httpx.AsyncClient` mit einem `asyncio.Semaphore`, das auf das Limit Ihres Kontos ausgelegt ist. Das Skript liest `concurrency_limit` vom kostenlosen Credits-Endpoint, sodass es sich anpasst, wenn der Support Ihr Limit erhöht. Suchanfragen über dem Limit bekämen ohnehin `429`; das Semaphore vermeidet diese verschwendeten Versuche.

Jede Aufgabe wiederholt temporäre Fehler mit wachsender Pause und gibt nach vier Fehlschlägen `None` zurück, sodass eine hartnäckige Suchanfrage den Batch nie blockiert.

*asyncio + httpx: parallele Suchanfragen unter dem Limit*

```python
"""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"]))
```

## Wie speichere ich tägliche Rankings in einer CSV-Datei?

Hängen Sie eine Zeile pro Ergebnis an, mit Tag, Keyword, Position, Link und den Einstellungen, die die API angewendet hat. `gl` und `device` aus `search_parameters` statt aus Ihren eigenen Variablen zu lesen bedeutet, dass die Datei festhält, was tatsächlich verwendet wurde.

Führen Sie das Skript einmal täglich mit cron oder dem Windows Task Scheduler aus. Drei Keywords auf Mobile kosten drei Credits pro Tag, etwa 90 im Monat.

*Die heutigen Rankings an rankings.csv anhängen*

```python
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"],
            })
```

## Welchen Python-HTTP-Client sollte ich verwenden?

Verwenden Sie `requests` für Skripte und Cron-Jobs: Es ist einfach und sein Retry-Adapter ist ausgereift. Verwenden Sie `httpx`, wenn Sie asynchronen Code benötigen, etwa für eine Web-App, einen Agenten oder eine Charge von Hunderten Keywords. Beide senden dieselbe Anfrage und erhalten dasselbe JSON; die API ist es egal, welches Sie wählen.

Vermeiden Sie sehr kurze Timeouts bei beiden Bibliotheken. Ein Client, der nach fünf Sekunden aufgibt, sendet möglicherweise eine Suche erneut, die noch lief, und zahlt doppelt.

## Wie viel kostet mein Skript?

Zählen Sie Suchanfragen, nicht Ergebnisse: Ein Aufruf ist eine Credit, wenn er erfolgreich ist. Ein Job mit 500 Keywords, je einer Seite, jeden Tag über 30 Tage, sind 15.000 Suchanfragen. Beim 25.000 Suchanfragen-Paket (18,75 $) bleibt reichlich Spielraum, und Vorausbezahlte Such-Credits verfallen nie: ungenutzte Suchen bleiben auf Ihrem Konto, bis Sie sie verwenden.

Prüfen Sie den Kontostand aus dem Code mit dem `credits()`-Helper oben; das kostet nichts.

## Python-Fragen

### Gibt es ein SerpCrypto-Paket auf PyPI?

Nein. Die Beispiele rufen den HTTPS-Endpoint mit `requests` oder `httpx` auf, zwei weit verbreiteten Bibliotheken, es gibt also nichts von uns zu installieren oder zu aktualisieren. Der Client oben hat etwa 40 Zeilen und gehört Ihnen.

### Welche Python-Versionen unterstützt dieser Code?

Python 3.9 und neuer. Das asynchrone Beispiel verwendet `asyncio.run`, verfügbar seit Python 3.7, und der Rest nutzt nur die Standardbibliothek plus `requests` oder `httpx`.

### Kann ich die API aus einem Jupyter-Notebook verwenden?

Ja. Setzen Sie `SERPCRYPTO_API_KEY`, bevor Sie Jupyter starten, oder lesen Sie den Schlüssel mit `getpass` im Notebook, damit er nicht in einer gespeicherten Zelle landet. Verwenden Sie im Notebook `await main(...)` statt `asyncio.run(main(...))`.

### Wie mache ich aus Ergebnissen ein pandas DataFrame?

Übergeben Sie die Liste der Ergebnis-Dictionaries an `pandas.DataFrame(data["organic_results"])`. Jedes Feld wird zu einer Spalte; fehlende optionale Felder wie `date` werden zu leeren Zellen.

---

SerpCrypto: SerpCrypto ist eine SERP-API für Entwickler und KI-Agenten, die Google- und Bing-Ergebnisse als JSON zurückgibt und mit Krypto bezahlt wird, ohne Ausweisupload. Vorausbezahlte Such-Credits ab 0,30 $/1K Suchanfragen verfallen nie. Ohne KYC — kein Ausweis, kein Selfie, keine Dokumente. Mit Krypto bezahlen.
