← Back to blog

Build a Google Rank Tracker in Python (2026 Tutorial)

Build a Google rank tracker in Python: query a SERP API, find your domain in organic results, store history in SQLite — ~$0.0006 per keyword check.

1 min read

A rank tracker is the simplest high-value SEO tool you can build: query Google for a keyword, find your domain, record the position, repeat daily. Here’s a complete one in Python using serp.cheap.

0. Sanity-check your key

Export your key and hit the API once with curl before writing any Python:

export SERP_CHEAP_API_KEY="your-key"

curl -s https://api.serp.cheap/v1/search \
  -H "X-API-Key: $SERP_CHEAP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"q":"project management software","gl":"us"}'

You get back an organic[] array with position, title, link, and snippet per result. That’s everything a rank tracker needs.

1. Find your position

import os
import requests

API_KEY = os.environ["SERP_CHEAP_API_KEY"]

def get_rank(keyword, domain, gl="us"):
    r = requests.post(
        "https://api.serp.cheap/v1/search",
        headers={"X-API-Key": API_KEY},
        json={"q": keyword, "gl": gl},
        timeout=30,
    )
    r.raise_for_status()
    for result in r.json()["organic"]:
        if domain.lower() in result["link"].lower():
            return result["position"]
    return None  # genuinely not in the results

print(get_rank("project management software", "asana.com"))

2. Store history in SQLite

One subtlety: a failed request and “not ranked” are different things. If the API call times out and you store None, your history shows a false ranking drop. So catch request errors, log them, and skip the row — only store None when the search actually ran and your domain wasn’t there.

import sqlite3
import datetime
import logging

logging.basicConfig(level=logging.INFO,
                    format="%(asctime)s %(levelname)s %(message)s")

db = sqlite3.connect("ranks.db")
db.execute("""CREATE TABLE IF NOT EXISTS ranks
  (date TEXT, keyword TEXT, domain TEXT, position INTEGER)""")

def record(keyword, domain, gl="us"):
    try:
        pos = get_rank(keyword, domain, gl)
    except requests.RequestException as e:
        logging.warning("skipped %r: %s", keyword, e)
        return "skipped"  # no row written — retry on the next run
    db.execute("INSERT INTO ranks VALUES (?,?,?,?)",
               (datetime.date.today().isoformat(), keyword, domain, pos))
    db.commit()
    return pos

3. Track a list daily

KEYWORDS = ["project management software", "best crm", "time tracking app"]
DOMAIN = "yoursite.com"

for kw in KEYWORDS:
    pos = record(kw, DOMAIN)
    if pos == "skipped":
        print(f"{kw}: skipped (request failed, no row written)")
    else:
        print(f"{kw}: {f'#{pos}' if pos else 'not in top results'}")

Example output:

project management software: #4
best crm: not in top results
time tracking app: #12

And when a request fails, the log shows the skip instead of polluting the database:

2026-06-10 07:00:18 WARNING skipped 'best crm': HTTPSConnectionPool(host='api.serp.cheap', port=443): Read timed out. (read timeout=30)

Schedule it with cron (0 7 * * *) or GitHub Actions for a daily snapshot.

4. The cost

Each keyword check is one request. 100 keywords/day ≈ $0.06/day fresh — and repeated checks hit the cache at half price. Compare that to hosted rank trackers charging $20–$100+/month.

Next

Try serp.cheap

Track 100 keywords daily for about $0.06/day. 100 free searches on signup — no card required; pay-as-you-go from $0.75/1k after that, and credits stay valid for 12 months.

Frequently asked questions

How do I track Google rankings in Python?+

Query a SERP API for your keyword, then find your domain in the organic[] results and record its position. Run it on a schedule and store the history. serp.cheap makes each check cost ~$0.0006.

How much does rank tracking cost?+

One keyword in one country is one request. Tracking 100 keywords daily is ~100 requests/day ≈ $0.06/day fresh on serp.cheap, less with cache hits.

Get your API key

Cheapest direct, pay by card or crypto, no KYC. Or use a marketplace.