Sıfırdan rank tracker: Search Console API ve SQLite ile

Ücretli rank tracker kullanmadan sıralama takibi yapmak isteyen herkesin aklına ilk gelen şey Google'ı kendi betiğiyle sorgulamak oluyor. Bunu yapmayın. Google sonuçlarını otomatik olarak kazımak Google'ın hizmet şartlarına aykırı, ayrıca kısa sürede CAPTCHA ve IP engeliyle karşılaşırsınız. Proxy havuzu kurmak, tarayıcı parmak izi taklit etmek gibi yollar hem etik değil hem de bakımı bitmeyen bir iş.

Benim çözümüm elimdeki en güvenilir veriyi kullanmak: Search Console. Google'ın kendi ölçtüğü gösterim ve pozisyon verisini her gün çekip SQLite'a yazıyorum, haftalık karşılaştırmayla en çok yükselen ve düşen sorguları listeliyorum.

Önce dürüst bir uyarı: ortalama pozisyon ne demek

Search Console'daki pozisyon, klasik rank tracker'ların verdiği "bugün saat 09:00'da İstanbul'dan masaüstünde 7. sıradasınız" bilgisi değil. Sayfanızın o sorgu için gösterildiği tüm gösterimlerin ortalama en üst pozisyonu. Farklı cihazlar, farklı şehirler, kişiselleştirme ve farklı saatler aynı ortalamaya karışır.

Bunun iki sonucu var. Birincisi, gösterim almadığınız bir sorgu için veri yoktur; 60. sıradaysanız ve kimse o kadar derine inmiyorsa, o sorgu listenizde görünmez. İkincisi, pozisyon değişimini yorumlarken gösterim sayısına da bakmak gerekir. Günde 3 gösterim alan bir sorgunun pozisyonu 6'dan 14'e zıplayabilir ve bu çoğu zaman sadece gürültüdür.

Buna rağmen, trend takibi için bu veri bence klasik tek noktalı kontrollerden daha değerli. Gerçek kullanıcıların gördüğü sonuçlardan geliyor ve ücretsiz.

Gerçek SERP pozisyonu gerekiyorsa

Belirli bir şehirde, belirli bir cihazda, belirli bir günde tam olarak kaçıncı sırada olduğunuzu bilmeniz gerekiyorsa, bunun yasal yolu ücretli SERP API servisleridir. Bu servisler sorguyu kendi altyapılarında çalıştırıp sonucu JSON olarak döner; sorgu başına ücret alırlar. Birkaç yüz kritik anahtar kelime için bu mantıklı olabilir. Ben ise kendi projelerimde Search Console verisiyle yetiniyorum; aşağıdaki yapı da buna göre.

Hazırlık

  1. Google Cloud'da bir proje açın, Google Search Console API'yi etkinleştirin.
  2. Bir servis hesabı oluşturup JSON anahtarını indirin.
  3. Servis hesabının e-posta adresini Search Console'da mülke kullanıcı olarak ekleyin (okuma izni yeterli).
  4. Kütüphaneleri kurun: pip install google-api-python-client google-auth.

API kurulumu, kimlik doğrulama ve sayfalama konusunu daha ayrıntılı olarak Search Console API ile yedekleme yazısında anlattım. Burada aynı temelin üstüne takip mantığını kuruyorum.

Veriyi toplayan betik

Betik, üç gün önceki günün verisini sorgu ve sayfa boyutlarıyla çekiyor. Search Console verisi birkaç gün gecikmeli kesinleştiği için bugünü ya da dünü çekmiyorum. API istek başına en fazla 25.000 satır döner, bu yüzden startRow ile sayfalıyorum.

topla.py
import sqlite3, sys
from datetime import date, timedelta
from google.oauth2 import service_account
from googleapiclient.discovery import build

SITE = "sc-domain:ornek.com"          # Search Console mülkü
ANAHTAR = "servis-hesabi.json"        # servis hesabı anahtarı
DB = "siralama.db"

kimlik = service_account.Credentials.from_service_account_file(
    ANAHTAR, scopes=["https://www.googleapis.com/auth/webmasters.readonly"])
servis = build("searchconsole", "v1", credentials=kimlik)

def gunu_cek(gun):
    satirlar, baslangic = [], 0
    while True:
        govde = {"startDate": gun, "endDate": gun, "dimensions": ["query", "page"],
                 "rowLimit": 25000, "startRow": baslangic}
        yanit = servis.searchanalytics().query(siteUrl=SITE, body=govde).execute()
        parca = yanit.get("rows", [])
        satirlar.extend(parca)
        if len(parca) < 25000:
            return satirlar
        baslangic += 25000

def kaydet(gun, satirlar):
    db = sqlite3.connect(DB)
    db.execute("""CREATE TABLE IF NOT EXISTS pozisyon (
        gun TEXT, sorgu TEXT, sayfa TEXT, tiklama INTEGER, gosterim INTEGER,
        pozisyon REAL, PRIMARY KEY (gun, sorgu, sayfa))""")
    db.executemany("INSERT OR REPLACE INTO pozisyon VALUES (?,?,?,?,?,?)",
        [(gun, r["keys"][0], r["keys"][1], r["clicks"], r["impressions"], r["position"])
         for r in satirlar])
    db.commit()
    db.close()

if __name__ == "__main__":
    # Parametre verilirse o kadar gün geriye doldurur (ilk kurulum için)
    geri = int(sys.argv[1]) if len(sys.argv) > 1 else 1
    for i in range(3, 3 + geri):
        gun = (date.today() - timedelta(days=i)).isoformat()
        satirlar = gunu_cek(gun)
        kaydet(gun, satirlar)
        print(gun, len(satirlar), "satır")

İlk kurulumda python topla.py 30 ile son 30 günü dolduruyorum, sonra cron ile her sabah parametresiz çalıştırıyorum. Search Console 16 aylık veri tuttuğu için isterseniz çok daha geriye de gidebilirsiniz.

Haftalık hareket raporu

Rapor tarafında her sorgu+sayfa çifti için son 7 günün ve önceki 7 günün pozisyonunu hesaplıyorum. Günlük pozisyonların basit ortalamasını değil, gösterimle ağırlıklı ortalamasını alıyorum; çünkü 1 gösterimli bir günle 500 gösterimli bir günün aynı ağırlıkta olması yanıltıcı olur. Çok az gösterim alan satırları da eşik ile dışarıda bırakıyorum.

rapor.py
import sqlite3
from datetime import date, timedelta

DB, ESIK = "siralama.db", 20   # her iki haftada en az 20 gösterim
db = sqlite3.connect(DB)

def hafta(bas, bit):
    # Gösterimle ağırlıklı ortalama pozisyon ve toplam gösterim
    sql = ("SELECT sorgu, sayfa, SUM(pozisyon * gosterim) / SUM(gosterim), SUM(gosterim) "
           "FROM pozisyon WHERE gun BETWEEN ? AND ? GROUP BY sorgu, sayfa")
    return {(s, u): (p, g) for s, u, p, g in db.execute(sql, (bas, bit))}

son = date.today() - timedelta(days=3)
gun = lambda n: (son - timedelta(days=n)).isoformat()
bu, onceki = hafta(gun(6), gun(0)), hafta(gun(13), gun(7))

hareket = []
for anahtar, (p, g) in bu.items():
    if anahtar in onceki and g >= ESIK and onceki[anahtar][1] >= ESIK:
        eski = onceki[anahtar][0]
        hareket.append((eski - p, anahtar, eski, p))   # pozitif fark = yükseliş

hareket.sort()
print("EN ÇOK DÜŞENLER")
for fark, (sorgu, sayfa), eski, yeni in [h for h in hareket if h[0] < 0][:10]:
    print(f"{eski:5.1f} -> {yeni:5.1f}  {sorgu}  {sayfa}")
print("\nEN ÇOK YÜKSELENLER")
for fark, (sorgu, sayfa), eski, yeni in [h for h in reversed(hareket) if h[0] > 0][:10]:
    print(f"{eski:5.1f} -> {yeni:5.1f}  {sorgu}  {sayfa}")

Çıktı, her satırda önceki haftanın ve bu haftanın pozisyonunu, sorguyu ve URL'yi verir. Pozisyon sayısı küçüldükçe iyileşme olduğu için farkı "eski eksi yeni" olarak hesaplıyorum; pozitif değer yükseliş anlamına geliyor.

Neden sorgu+sayfa çifti

Sadece sorgu bazında takip yaparsanız önemli bir olayı kaçırırsınız: aynı sorgu için Google'ın gösterdiği URL'nin değişmesi. Bir hafta kategori sayfanız, ertesi hafta bir blog yazınız sıralanıyorsa, bu genellikle kanibalizasyonun ya da Google'ın niyet algısının değiştiğinin işaretidir. Çift bazında saklayınca bu durum raporda bir satırın kaybolup yenisinin belirmesi şeklinde görünür. İsterseniz rapora "geçen hafta vardı, bu hafta yok" listesini de eklemek birkaç satırlık iş.

Bir de şunu bilmek lazım: Search Console gizlilik nedeniyle çok nadir yapılan sorguları raporda göstermez. Sorgu boyutuyla çektiğiniz toplamlar, sadece sayfa boyutuyla çektiğiniz toplamlardan her zaman daha düşük çıkar. Bu bir hata değil, verinin doğası.

Pratik ayarlar

  • Zamanlama: Cron ile her sabah topla.py, pazartesi sabahları da rapor.py çalıştırıyorum. Çıktıyı e-postaya ya da bir mesajlaşma botuna yönlendirmek kolay.
  • Eşik: 20 gösterim benim küçük siteler için kullandığım değer. Büyük sitede eşiği yükseltmezseniz rapor gürültüyle dolar.
  • Veritabanı boyutu: Sorgu+sayfa satırları hızlı büyür. Aylar sonra dosya şişerse eski günleri haftalık özetlere dönüştürüp ham satırları silebilirsiniz.
  • Takip listesi: Tüm sorguları izlemek yerine önemli anahtar kelimeler için ayrı bir tablo tutup raporu onlara göre süzmek de mümkün.
  • Görselleştirme: Belirli bir sorgunun günlük pozisyon grafiği için SQLite'tan CSV alıp GSC analiz aracına ya da bir tabloya aktarmak yeterli oluyor.

Pozisyon düşüşü gördüğünüz sorgular için sonraki adım genellikle sayfanın kendisine ve sonuç sayfasının değişip değişmediğine bakmaktır. 4-15 bandında kalan sorgulara ise ayrı bir gözle bakmakta fayda var; bu konuyu Performans raporundaki gizli fırsatlar yazısında anlattım.

Özetle

İhtiyaçÖnerim
Trend takibi, ücretsizSearch Console API + SQLite (bu yazıdaki yapı)
Belirli konum/cihazda kesin sıraÜcretli SERP API servisi
Google'ı kendi betiğinizle kazımakYapmayın; şartlara aykırı ve engellenir
Tek bir sorgunun anlık kontrolüGizli pencerede elle arama, sonucu kesin kabul etmeden

Search Console'un ortalama pozisyonu mükemmel bir ölçü değil ama tutarlı, ücretsiz ve gerçek gösterimlere dayanıyor. Her gün kaydedip haftalık farklara bakmak, hangi sayfalarda bir şeylerin değiştiğini fark etmek için bana fazlasıyla yetiyor.

Comments / questions

If you have a question about any topic or wish to contact me: Telegram or send an email to [email protected] Thanks!

Related pages