# SERP API di Python: requests, httpx, dan asyncio

> Gunakan SERP API SerpCrypto di Python: klien requests dengan retry, httpx async dengan batas konkurensi, paginasi, dan ekspor CSV. Kode yang sudah diuji.

- URL: https://serpcrypto.com/id/docs/python/
- Terakhir diperbarui: 2026-10-22
- Penerbit: SerpCrypto (https://serpcrypto.com)

Klien yang dapat digunakan ulang dengan retry, loop paginasi yang berhenti saat hasil habis, pencarian async yang dibatasi sesuai batas konkurensi Anda, dan CSV harian untuk ranking. Kode siap salin-tempel, sudah dicek sintaksnya, tanpa paket dari kami yang perlu diinstal.

**Jawaban singkat — Bagaimana cara memanggil SERP API dari Python?**

Kirim GET request ke `https://serpcrypto.com/api/v1/search` dengan `requests` atau `httpx`, API key Anda di header `Authorization: Bearer` dan kueri di `params`, lalu baca `response.json()`. **SerpCrypto** menagih 1 kredit per pencarian yang berhasil, mulai dari US$0,30/1K pencarian, dan retry untuk panggilan yang gagal gratis. Bayar dengan kripto, tanpa KYC. Kode di bawah ini hanya membutuhkan `requests` atau `httpx`.

## Setup Python sekilas

| Atribut | Nilai |
| --- | --- |
| Instal | `pip install requests` atau `pip install httpx` |
| API key | Environment variable `SERPCRYPTO_API_KEY` |
| Header | `Authorization: Bearer <key>` |
| Timeout | 60 hingga 90 detik: pencarian berjalan secara live |
| Retry | Hanya 429, 502, dan 504, dengan backoff; error gratis |
| Pencarian paralel | Hingga `concurrency_limit` dari `GET /credits` |

## Bagaimana cara menyiapkan klien Python yang dapat digunakan ulang?

Buat satu `requests.Session` dengan API key di header dan kebijakan retry untuk tiga error sementara. Satu session menggunakan ulang koneksi, jadi loop pencarian lebih sedikit menghabiskan waktu untuk TLS handshake. Simpan file sebagai `serp_client.py`; contoh berikutnya mengimpornya.

`Retry` dari urllib3 menunggu lebih lama sebelum setiap percobaan baru dan mematuhi header `Retry-After` jika dikirim. Ini tidak pernah me-retry `400`, `401`, atau `402`, yang perlu diperbaiki, bukan dicoba ulang.

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

## Bagaimana cara mengumpulkan lebih dari 10 hasil?

Minta halaman berikutnya satu per satu. Sekitar 10 hasil organik per halaman, sebagaimana yang disajikan Google sejak berhenti mematuhi num=100 pada September 2025; setiap halaman tambahan dikenai satu kredit lagi. Berhenti begitu `pagination.next_page` tidak ada: tidak ada lagi yang bisa diambil, dan kredit Anda tetap utuh.

Untuk sebagian besar pekerjaan rank tracking, halaman pertama atau tiga halaman pertama sudah cukup, karena klik terkonsentrasi di sana. Tiga puluh hasil untuk satu kata kunci menagih tiga kredit.

*Paginasi: hingga tiga halaman, berhenti lebih awal*

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

## Bagaimana cara menjalankan banyak pencarian secara paralel?

Gunakan `httpx.AsyncClient` dengan `asyncio.Semaphore` yang disesuaikan dengan batas akun Anda. Skrip membaca `concurrency_limit` dari endpoint kredit gratis, sehingga menyesuaikan saat support menaikkan batas Anda. Pencarian di atas batas tetap akan mendapat `429`; semaphore menghindari percobaan yang terbuang itu.

Setiap task me-retry error sementara dengan jeda yang makin panjang dan mengembalikan `None` setelah empat kegagalan, sehingga satu kueri yang membandel tidak pernah memblokir seluruh batch.

*asyncio + httpx: pencarian paralel di bawah batas*

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

## Bagaimana cara menyimpan ranking harian ke file CSV?

Tambahkan satu baris per hasil, berisi tanggal, kata kunci, posisi, tautan, dan pengaturan yang diterapkan API. Membaca `gl` dan `device` dari `search_parameters`, bukan dari variabel Anda sendiri, berarti file mencatat apa yang benar-benar digunakan.

Jalankan skrip sekali sehari dengan cron atau Windows Task Scheduler. Tiga kata kunci di mobile menagih tiga kredit sehari, sekitar 90 sebulan.

*Tambahkan ranking hari ini ke 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"],
            })
```

## Klien HTTP Python mana yang sebaiknya saya gunakan?

Gunakan `requests` untuk skrip dan cron job: sederhana dan adapter retry-nya sudah matang. Gunakan `httpx` saat Anda butuh kode async, seperti web app, agent, atau batch berisi ratusan kueri. Keduanya mengirim permintaan yang sama dan menerima JSON yang sama; API tidak peduli mana yang Anda pilih.

Hindari timeout yang terlalu singkat pada kedua library. Klien yang menyerah setelah lima detik bisa mengirim ulang pencarian yang masih berjalan dan membayar dua kali.

## Berapa biaya skrip saya?

Hitung pencarian, bukan hasil: satu panggilan adalah satu kredit bila berhasil. Job 500 kueri, satu halaman per kueri, setiap hari selama 30 hari, berarti 15.000 pencarian. Dengan paket 25.000 pencarian (US$18,75), masih ada sisa lebih dari cukup, dan Kredit pencarian prabayar tidak pernah kedaluwarsa: pencarian yang belum terpakai tetap ada di akun Anda sampai Anda menggunakannya.

Cek saldo dari kode dengan helper `credits()` di atas; tidak ada biayanya.

## Pertanyaan seputar Python

### Apakah ada paket SerpCrypto di PyPI?

Tidak. Contoh-contohnya memanggil endpoint HTTPS dengan `requests` atau `httpx`, dua library yang banyak dipakai, jadi tidak ada milik kami yang perlu diinstal atau diperbarui. Klien di atas hanya sekitar 40 baris dan sepenuhnya milik Anda.

### Versi Python mana yang didukung kode ini?

Python 3.9 dan yang lebih baru. Contoh async menggunakan `asyncio.run`, tersedia sejak Python 3.7, dan sisanya hanya memakai standard library plus `requests` atau `httpx`.

### Bisakah saya memakai API dari Jupyter notebook?

Bisa. Set `SERPCRYPTO_API_KEY` sebelum memulai Jupyter, atau baca API key dengan `getpass` di dalam notebook agar tidak ikut tersimpan di cell. Di notebook, gunakan `await main(...)` alih-alih `asyncio.run(main(...))`.

### Bagaimana cara mengubah hasil menjadi pandas DataFrame?

Teruskan list berisi dictionary hasil ke `pandas.DataFrame(data["organic_results"])`. Setiap field menjadi satu kolom; field opsional yang tidak ada seperti `date` menjadi cell kosong.

---

SerpCrypto: SerpCrypto adalah SERP API untuk developer dan AI agent yang mengembalikan hasil pencarian Google dan Bing dalam format JSON, dibayar dengan kripto tanpa unggah identitas. Kredit pencarian prabayar mulai dari US$0,30/1K pencarian tidak pernah kedaluwarsa. Tanpa KYC — tanpa ID, tanpa selfie, tanpa dokumen. Bayar dengan kripto.
