E-ticarette rekabet avantajı sağlamanın en doğrudan yolu, pazar dinamiklerini ve rakip fiyatlandırma stratejilerini gerçek zamanlı izlemekten geçer. Bir fiyat takip botu, hedef web sitelerindeki ürün fiyatlarını, stok durumlarını ve kampanya değişikliklerini otomatik olarak toplayıp yapılandırılmış verilere dönüştürerek bu süreci insan müdahalesinden bağımsız hale getirir. Python ekosistemi, sunduğu güçlü veri kazıma (scraping) ve otomasyon kütüphaneleri sayesinde bu tür sistemleri sıfırdan inşa etmek için en esnek zemini sunar.
Pazar yerleri ve bağımsız e-ticaret siteleri, fiyat değişimlerini saniyeler içinde uygulayabilir. Bu verileri düzenli aralıklarla çekmek, kendi fiyatlandırma motorunuzu beslemek veya yalnızca indirimleri yakalamak için çalışan sağlam bir mimarinin nasıl kurulacağını adım adım inceleyelim.
Fiyat takip botu mimarisini planlama ve kütüphane seçimi
Bir fiyat takip botu tasarlarken veriyi sunan sitenin teknik yapısını anlamak, kullanılacak araçları belirlemenin ilk kuralıdır. Web siteleri temel olarak iki farklı mimariyle veri sunar: sunucu taraflı oluşturulan (server-side rendered - SSR) statik sayfalar ve istemci tarafında JavaScript ile yüklenen (client-side rendered - CSR) dinamik sayfalar.
İhtiyacınıza göre tercih edebileceğiniz iki ana yaklaşım bulunur:
| Araç Grubu | Kullanılan Kütüphaneler | En Uygun Olduğu Senaryo | Kaynak Tüketimi |
|---|---|---|---|
| Hafif / Hızlı Kazıyıcılar | Requests, HTTPX, BeautifulSoup |
Statik HTML dönen, JS ile fiyat yüklemeyen siteler | Çok Düşük (Yüksek Hız) |
| Headless Tarayıcılar | Selenium, Playwright |
Single Page Application (SPA), React/Vue tabanlı siteler | Orta - Yüksek (Daha Yavaş) |
Eğer hedef platform fiyat bilgisini ilk HTTP yanıtı içinde düz HTML olarak gönderiyorsa, tarayıcı çalıştırmak gereksiz bellek harcar. Ancak günümüz e-ticaret sitelerinin büyük bölümü bot koruma sistemleri barındırır veya fiyatı API çağrıları sonrası DOM ağacına JavaScript ile enjekte eder. Bu gibi durumlarda Playwright veya Selenium gibi headless (grafik arayüzü olmayan) tarayıcılar devreye girer.
Python ile temel bir fiyat kazıma betiği oluşturma
İstemci tarafında çalışan sayfalar için modern, hızlı ve hata yönetimi güçlü olan Playwright kütüphanesi ideal bir tercihtir. Aşağıdaki adımlar, bir ürünün başlığını ve fiyatını headless tarayıcı kullanarak çekmenin mantığını gösterir.
1. Gerekli paketlerin kurulumu
Terminal üzerinde Python ortamınızı hazırlayarak işe başlayabilirsiniz:
pip install playwright
playwright install
2. Kazıma mantığını kodlama
Hedef sayfayı ziyaret edip DOM üzerindeki ilgili CSS seçicilerini (selectors) bekleyen ve veriyi çeken örnek bir yapı oluşturalım:
import asyncio
from playwright.async_api import async_playwright
async def urun_fiyati_getir(url: str, selector_fiyat: str, selector_baslik: str):
async with async_playwright() as p:
# Bot tespit mekanizmalarını tetiklememek için gerçekçi bir User-Agent tanımlayın
browser = await p.chromium.launch(headless=True)
context = await browser.new_context(
user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
)
page = await context.new_page()
try:
# Sayfanın DOM ağacının oturmasını bekleyin
await page.goto(url, wait_until="domcontentloaded", timeout=30000)
# Fiyat etiketinin yüklenmesini bekle
await page.wait_for_selector(selector_fiyat, timeout=10000)
baslik = await page.locator(selector_baslik).inner_text()
ham_fiyat = await page.locator(selector_fiyat).inner_text()
return {
"baslik": baslik.strip(),
"fiyat": ham_fiyat.strip(),
"url": url
}
except Exception as e:
print(f"Hata oluştu ({url}): {str(e)}")
return None
finally:
await browser.close()
Bu fonksiyon, belirtilen URL'ye gider, ilgili HTML elemanının ekranda belirmesini bekler ve metin içeriğini alır. Ancak veriyi yalnızca çekmek yetmez; fiyatın sayısal bir değere dönüştürülmesi gerekir.
3. Fiyat verisini temizleme
Web sitelerinden çekilen fiyatlar genellikle para birimi sembolleri, boşluklar veya noktalama işaretleri içerir (örneğin "1.250,50 TL" veya "$99.99"). Bu metinleri matematiksel karşılaştırmalara sokabilmek için temizleyen yardımcı bir fonksiyon yazılmalıdır:
import re
def fiyati_sayiya_donustur(ham_fiyat: str) -> float:
# Sayılar, virgül ve nokta dışındaki tüm karakterleri temizle
temiz_metin = re.sub(r"[^\d,\.]", "", ham_fiyat)
# Türkiye formatı: 1.500,50 -> Noktaları kaldır, virgülü noktaya çevir
if "," in temiz_metin and "." in temiz_metin:
temiz_metin = temiz_metin.replace(".", "").replace(",", ".")
elif "," in temiz_metin:
temiz_metin = temiz_metin.replace(",", ".")
try:
return float(temiz_metin)
except ValueError:
return 0.0
Veri saklama ve fiyat değişim takibi
Bir fiyat takip botu, geçmiş veriyi hatırlamadığı sürece yalnızca anlık bir kazıyıcıdan ibarettir. Değişimleri algılamak için ilişkisel bir veri tabanı (örneğin SQLite veya PostgreSQL) kullanmak en kararlı yöntemdir.
Sistemin temel veri akış şeması şu şekilde kurgulanabilir:
[ Hedef E-Ticaret Sayfası ]
│
▼ (Kazıma Motoru: Playwright / HTTPX)
[ Ham Fiyat & Stok Verisi ]
│
▼ (Normalizasyon & Regex Temizliği)
[ Temiz Sayısal Veri ] ──► [ Veri Tabanı Kaydı (SQLite / PostgreSQL) ]
│
▼ (Eski Fiyat ile Karşılaştırma)
[ Değişim Eşiği Aşıldı mı? ]
│ │
EVET HAYIR
│ │
▼ ▼
[ Uyarı Tetikle ] [ İşlemi Sonlandır / Uyku Modu ]
(Telegram, Webhook, E-posta)
SQLite kullanarak ürünlerin son durumunu ve fiyat geçmişini iki tablolu basit bir şemada tutabilirsiniz:
urunlerTablosu: Ürün ID'si, ürün adı, takip URL'si, son görülen fiyat ve son kontrol tarihi.fiyat_gecmisiTablosu: Ürün ID'si, tespit edilen fiyat ve zaman damgası (timestamp).
Bot her çalıştığında, kazınan yeni fiyat urunler tablosundaki mevcut fiyatla karşılaştırılır. Eğer yeni fiyat eskisinden düşükse, fiyat_gecmisi tablosuna yeni bir satır eklenir ve sistem bir uyarı mekanizmasını tetikler.
Bot koruma sistemlerini aşma ve sürdürülebilirlik
E-ticaret siteleri, Cloudflare, DataDome veya Akamai gibi gelişmiş bot engelleme çözümleri kullanır. Bir IP adresinden gelen sıra dışı ve hızlı istekler kısa sürede CAPTCHA duvarına veya doğrudan IP engellemesine (403 Forbidden) takılır. Botunuzun kesintisiz çalışması için operasyonel olarak şu standartlara uymak gerekir:
- Dönüşümlü Proxy (Rotating Proxy) Kullanımı: Her istekte veya belirli periyotlarda IP adresini değiştiren konut tipi (residential) proxy ağları kullanın. Veri merkezi (datacenter) IP'leri güvenlik duvarları tarafından kolayca tespit edilir.
- İstek Aralıklarını Rastgele Hale Getirme: İstekleri sabit aralıklarla (örneğin tam olarak 60 saniyede bir) atmak yerine,
time.sleep(random.uniform(5, 15))gibi rastgele gecikmeler tanımlayarak insan davranışını taklit edin. - Başlık (Header) Yönetimi: Yalnızca
User-Agentdeğil,Accept-Language,Sec-Ch-UaveRefererbaşlıklarını da tam ve tarayıcı profilleriyle tutarlı olacak şekilde gönderin. - Gereksiz İstekleri Engelleme: Headless tarayıcı kullanırken CSS, font ve görsel (image) dosyalarının yüklenmesini engelleyerek bant genişliğini koruyun ve sayfa yüklenme hızını 3-4 kat artırın.
Bildirim mekanizması: Değişimi anında haber alma
Fiyat hareketini yakaladıktan sonra bu veriyi son kullanıcıya iletmek, sistemin çıktısını anlamlı kılan son adımdır. Telegram Bot API, bu işlem için en hızlı ve ücretsiz çözümü sunar.
requests kütüphanesini kullanarak doğrudan Telegram kanalına veya kullanıcısına mesaj iletmek birkaç satır kodla mümkündür:
import requests
def telegram_bildirimi_gonder(token: str, chat_id: str, mesaj: str):
url = f"https://api.telegram.org/bot{token}/sendMessage"
payload = {
"chat_id": chat_id,
"text": mesaj,
"parse_mode": "Markdown"
}
try:
requests.post(url, json=payload, timeout=10)
except requests.RequestException as e:
print(f"Bildirim gönderilemedi: {e}")
Fiyat düştüğünde tetiklenecek mesaj şablonu, eski fiyatı, yeni fiyatı ve doğrudan ürünün bağlantısını içermelidir. Böylece kullanıcı herhangi bir arayüze girmeden kritik fiyat değişikliklerinden anında haberdar olur.
Üretime alma ve çalıştırma döngüsü
Geliştirilen botun bir dizüstü bilgisayarda açık kalması yerine ucuz bir Linux sanal sunucusunda (VPS) arka plan hizmeti olarak çalışması gerekir.
Linux ortamında bu akışı yönetmek için iki ana yöntem vardır:
- Cron İşleri (Cron Jobs): Eğer siteleri saat başı veya günde bir kez kontrol etmek yetiyorsa, Python betiğini Linux Cron servisine bağlayarak kaynak tüketimini sıfıra indirebilirsiniz.
- Systemd Servisi / Docker: 5-10 dakikada bir kontrol gereken dinamik pazarlarda, betiği Docker konteyneri içinde izole etmek ve bir
systemdservisi olarak arka planda sürekli ayakta tutmak en kararlı yaklaşımdır.
Sıkça sorulan sorular
E-ticaret sitelerinden fiyat verisi toplamak yasal mıdır?
Herkese açık, kimlik doğrulaması gerektirmeyen fiyat verilerini toplamak çoğu yargı bölgesinde ticari istihbarat sınırları içinde kabul edilir. Ancak sitelerin Hizmet Şartları (ToS) sözleşmelerini incelemek, sunucuya DDoS etkisi yaratacak sıklıkta istek atmamak ve kişisel verileri kazımamak yasal ve etik sınırlar içinde kalmak için zorunludur.
Site tasarımı değiştiğinde bot bozulur mu?
Evet. CSS seçicileri (class veya id isimleri) değiştiğinde bot veriyi bulamaz ve hata verir. Bu sorunu en aza indirmek için sınıflara (.price-current) bağımlı olmak yerine, data-testid gibi test etiketlerini veya semantik HTML elemanlarını hedeflemek daha uzun ömürlü bir yapı sağlar.
Aynı anda yüzlerce ürünü nasıl takip edebilirim?
Asenkron mimari (Python asyncio) burada devreye girer. Playwright kütüphanesinin eşzamanlı bağlamları (browser contexts) veya hafif yapılı siteler için HTTPX kütüphanesinin asenkron istemcisi kullanılarak yüzlerce URL, dakikalar yerine saniyeler içinde taranabilir.
Kararlı bir otomasyon için yol haritası
Başarılı bir fiyat izleme altyapısı kurarken şu dört katmanlı geliştirme prensibini uygulayın:
- Doğrulama: Kazıyacağınız sayfanın JavaScript gerektirip gerektirmediğini ağ trafiğini (DevTools > Network) inceleyerek teyit edin; API uç noktası varsa doğrudan JSON yanıtını hedefleyin.
- Normalizasyon: Ham metni her zaman standart bir para birimi ve kayan noktalı sayı (float/decimal) formatına indirgeyin.
- Savunma: Beklenmedik DOM değişikliklerine karşı
try-exceptblokları kurun ve seçici kırıldığında kazıyıcının tamamen çökmesini değil, log bırakmasını sağlayın. - Hafifletme: Tarayıcı motorlarını yalnızca gerçekten zorunlu olduğunda çalıştırın ve her oturum sonunda bellek sızıntılarını önlemek için oturumları kapatmayı unutmayın.