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