# SERP-API in Python: requests, httpx en asyncio

> Gebruik de SerpCrypto SERP-API in Python: een requests-client met retries, async httpx met een concurrency-limiet, paginering en CSV-export. Geteste code.

- URL: https://serpcrypto.com/nl/docs/python/
- Laatst bijgewerkt: 2026-10-22
- Uitgever: SerpCrypto (https://serpcrypto.com)

Een herbruikbare client met retries, een pagineringsloop die stopt wanneer de resultaten op zijn, async zoekopdrachten begrensd tot je concurrency-limiet, en een dagelijkse CSV voor rankings. Kopieer-en-plak-code, syntax gecontroleerd, zonder een package van ons te installeren.

**Snel antwoord — Hoe roep ik een SERP-API aan vanuit Python?**

Stuur een GET-request naar `https://serpcrypto.com/api/v1/search` met `requests` of `httpx`, je sleutel in de `Authorization: Bearer` header en de zoekopdracht in `params`, en lees dan `response.json()`. **SerpCrypto** rekent 1 credit per geslaagde zoekopdracht, vanaf US$ 0,30/1K zoekopdrachten, en retries van mislukte calls zijn gratis. Betalen met crypto, zonder KYC. De code hieronder heeft alleen `requests` of `httpx` nodig.

## Python-setup in één oogopslag

| Attribuut | Waarde |
| --- | --- |
| Installeren | `pip install requests` of `pip install httpx` |
| Sleutel | Omgevingsvariabele `SERPCRYPTO_API_KEY` |
| Header | `Authorization: Bearer <key>` |
| Timeout | 60 tot 90 seconden: een zoekopdracht draait live |
| Retry | Alleen 429, 502 en 504, met backoff; fouten zijn gratis |
| Parallelle zoekopdrachten | Tot `concurrency_limit` vanaf `GET /credits` |

## Hoe stel ik een herbruikbare Python-client in?

Maak één `requests.Session` met de sleutel in de headers en een retry-beleid voor de drie tijdelijke fouten. Een sessie hergebruikt verbindingen, zodat een loop van zoekopdrachten minder tijd kwijt is aan TLS-handshakes. Sla het bestand op als `serp_client.py`; de volgende voorbeelden importeren het.

`Retry` van urllib3 wacht langer voor elke nieuwe poging en respecteert een `Retry-After` header als die wordt meegestuurd. Het doet nooit een retry bij `400`, `401` of `402`, die een fix nodig hebben, geen tweede poging.

*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())
```

## Hoe verzamel ik meer dan 10 resultaten?

Vraag de volgende pagina's één voor één op. Ongeveer 10 organische resultaten per pagina, zoals Google levert sinds het in september 2025 stopte met num=100; elke extra pagina kost nog een credit. Stop zodra `pagination.next_page` ontbreekt: er is niets meer op te halen, en je houdt de credits.

Voor de meeste rank-tracking-taken zijn de eerste pagina of de eerste drie pagina's genoeg, omdat kliks zich daar concentreren. Dertig resultaten voor één keyword kosten drie credits.

*Paginering: tot drie pagina's, vroeg stoppen*

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

## Hoe draai ik veel zoekopdrachten parallel?

Gebruik `httpx.AsyncClient` met een `asyncio.Semaphore` afgestemd op de limiet van je account. Het script leest `concurrency_limit` uit het gratis credits-endpoint, zodat het zich aanpast wanneer support je limiet verhoogt. Zoekopdrachten boven de limiet zouden toch `429` krijgen; de semaphore voorkomt dat die pogingen verspild worden.

Elke taak doet een retry bij tijdelijke fouten met een groeiende pauze en retourneert `None` na vier mislukkingen, zodat één koppige query nooit de batch blokkeert.

*asyncio + httpx: parallelle zoekopdrachten onder de limiet*

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

## Hoe sla ik dagelijkse rankings op in een CSV-bestand?

Voeg één rij per resultaat toe, met de dag, het keyword, de positie, de link en de instellingen die de API heeft toegepast. Door `gl` en `device` uit `search_parameters` te lezen in plaats van uit je eigen variabelen, legt het bestand vast wat daadwerkelijk is gebruikt.

Draai het script één keer per dag met cron of de Windows Taakplanner. Drie keywords op mobiel kosten drie credits per dag, ongeveer 90 per maand.

*Voeg de rankings van vandaag toe aan rankings.csv*

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

## Welke Python HTTP-client moet ik gebruiken?

Gebruik `requests` voor scripts en cron jobs: het is eenvoudig en de retry-adapter is volwassen. Gebruik `httpx` wanneer je async-code nodig hebt, zoals een web-app, een agent of een batch van honderden zoekwoorden. Beide sturen hetzelfde verzoek en krijgen dezelfde JSON; de API maakt niet uit welke je kiest.

Vermijd zeer korte time-outs bij beide libraries. Een client die na vijf seconden opgeeft, kan een zoekopdracht opnieuw versturen die nog liep en betaalt dan voor beide.

## Hoeveel kost mijn script?

Tel zoekopdrachten, niet resultaten: één call is één credit wanneer die slaagt. Een job van 500 zoekwoorden, één pagina elk, elke dag gedurende 30 dagen, is 15.000 zoekopdrachten. Op het 25.000 zoekopdrachten pack (US$ 18,75) houd je ruim over, en Prepaid zoekcredits verlopen nooit: ongebruikte zoekopdrachten blijven op je account staan tot je ze gebruikt.

Controleer het saldo vanuit code met de `credits()` helper hierboven; dat kost niets.

## Python-vragen

### Is er een SerpCrypto-package op PyPI?

Nee. De voorbeelden roepen het HTTPS-endpoint aan met `requests` of `httpx`, twee veelgebruikte libraries, dus er is niets van ons om te installeren of bij te werken. De client hierboven is ongeveer 40 regels en die is van jou.

### Welke Python-versies ondersteunt deze code?

Python 3.9 en later. Het async-voorbeeld gebruikt `asyncio.run`, beschikbaar sinds Python 3.7, en de rest gebruikt alleen de standard library plus `requests` of `httpx`.

### Kan ik de API vanuit een Jupyter notebook gebruiken?

Ja. Stel `SERPCRYPTO_API_KEY` in voordat je Jupyter start, of lees de sleutel met `getpass` in het notebook, zodat die niet in een opgeslagen cel belandt. Gebruik in een notebook `await main(...)` in plaats van `asyncio.run(main(...))`.

### Hoe zet ik resultaten om naar een pandas DataFrame?

Geef de lijst met resultaat-dictionaries door aan `pandas.DataFrame(data["organic_results"])`. Elk field wordt een kolom; ontbrekende optionele fields zoals `date` worden lege cellen.

---

SerpCrypto: SerpCrypto is een SERP-API voor developers en AI-agents die Google- en Bing-resultaten als JSON retourneert, betaald met crypto zonder ID te uploaden. Prepaid zoekcredits vanaf US$ 0,30/1K zoekopdrachten verlopen nooit. Zonder KYC — geen ID, geen selfie, geen documenten. Betalen met crypto.
