Neden Otomatik Fiyat İzleme Maddeleri
Rekabetçi e-ticaret pazarlarında, fiyatlar sürekli değişir. Bir rakip fiyatlarını 2 AM'de %5 düşürebilir ve fark ettiğiniz zaman zaten bir satış gününü kaybettiniz. Otomatik fiyat izleme, rakip fiyatları sürekli takip ederek bu kör noktayı ortadan kaldırır ve gerçek zamanlı değişiklikler için sizi uyarır.
Rekabetçi kalmak için fiyatlar ayarlayan bir perakendeci olsanız da, bir marka izleme MAP (Minimum Reklamlı Fiyat) uyumluluk veya bir analist izleme piyasa trendleri, iyi yerleşik bir fiyat izleme sistemi hızlı bir şekilde öder. Tüm işi güvenilir kılan temel bileşen sağlam bir proxy altyapısıdır - onsuz, izleme istekleriniz saatlerce engellenir. E-ticaret veri koleksiyonuna daha geniş bir bakış için, bizi görün e-ticaret verileri kılavuzluk.
Bir Fiyat İzleme Sistemi Mimarisi
Bir üretim seviyesi fiyat izleme sistemi dört ana bileşene sahiptir: bir URL yöneticisi, bir hurda motoru, bir veri mağazası ve uyarı katmanı.
| Bitirme | Sorumluluk Sorumluluk Sorumluluk | Teknoloji Teknolojileri |
|---|---|---|
| URL Manager | Mağazalar hedef URL'ler, metadata'yı planlama ve frekans dökme | PostgreSQL, Redis |
| Yakalama Motoru | Fetches sayfaları referanslar aracılığıyla, fiyatlar | Python/Node.js, ProxyHat, BeautifulSoup /Cheerio |
| Data Store | Mağazalar fiyat tarihi zamantamps ile | PostgreSQL, TimescaleDB, ClickHouse |
| Uyarı Sistemi | Değişiklikleri gönderir, bildirimleri gönderir | Webhooks, Slack, E-posta, SMS |
Planlama Stratejisi
Tüm ürünlerin aynı izleme frekansına ihtiyacı yoktur. High-priority öğeleri (en üst 100 SKU'larınız, doğrudan rakip ürünleriniz) saatlik kontrollere ihtiyaç duyabilir, uzun kuyruk eşyaları günlük kontrol edilebilir. Öncelik:
- Fiyat dalgalanması: Fiyatlar değiştiren ürünler genellikle daha sık kontrollere ihtiyaç duyar.
- Gelir etkisi: En iyiler daha yüksek izleme önceliği hak ediyor.
- Rekabetçi yoğunluk: Birçok rakiple Kategoriler sıkı izlemeye ihtiyaç duyar.
İzleme için Proxy Rotation
Fiyat izleme, aynı URL'leri defalarca günler, haftalar ve aylar boyunca vurmak anlamına gelir. Bu model, anti-bot sistemlerinin tespit etmek için tasarlandığını tam olarak budur. Otomatik rotasyonla ev sahipleri önemlidir.
ProxyHat Build
# Standard rotating proxy (new IP per request)
http://USERNAME:PASSWORD@gate.proxyhat.com:8080
# Geo-targeted for regional pricing (e.g., US prices)
http://USERNAME-country-US:PASSWORD@gate.proxyhat.com:8080
# Session-based for multi-page price checks
http://USERNAME-session-price001:PASSWORD@gate.proxyhat.com:8080Fiyat kontrolü için, per-request rotasyonu en iyi çalışır, çünkü her fiyat kontrolü bağımsız bir operasyondır. Use Use Use Use Use Use geo-targetedants Bölgesel fiyat farklılıkları izlemede.
Python Uygulaması
İşte Python ile inşa edilen tam bir fiyat izleme sistemi, kullanarak ProxyHat's Python SDK.
Fiyat avlayıcı Modül
import requests
from bs4 import BeautifulSoup
import json
import time
import random
from datetime import datetime
from dataclasses import dataclass, asdict
PROXY_URL = "http://USERNAME:PASSWORD@gate.proxyhat.com:8080"
USER_AGENTS = [
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/124.0.0.0 Safari/537.36",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 Chrome/124.0.0.0 Safari/537.36",
]
@dataclass
class PriceResult:
url: str
price: float | None
currency: str | None
in_stock: bool
scraped_at: str
seller: str | None = None
def scrape_price(url: str, selectors: dict) -> PriceResult:
"""Scrape a product price from any e-commerce site."""
headers = {
"User-Agent": random.choice(USER_AGENTS),
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Language": "en-US,en;q=0.9",
}
proxies = {"http": PROXY_URL, "https": PROXY_URL}
try:
response = requests.get(url, headers=headers, proxies=proxies, timeout=30)
response.raise_for_status()
except requests.RequestException as e:
return PriceResult(
url=url, price=None, currency=None,
in_stock=False, scraped_at=datetime.utcnow().isoformat()
)
soup = BeautifulSoup(response.text, "html.parser")
price = extract_price(soup, selectors.get("price"))
currency = selectors.get("currency", "USD")
in_stock = check_stock(soup, selectors.get("stock"))
return PriceResult(
url=url,
price=price,
currency=currency,
in_stock=in_stock,
scraped_at=datetime.utcnow().isoformat(),
)
def extract_price(soup, selector: str) -> float | None:
"""Extract and parse price from a CSS selector."""
if not selector:
return None
el = soup.select_one(selector)
if not el:
return None
text = el.get_text(strip=True)
# Remove currency symbols, commas, spaces
cleaned = "".join(c for c in text if c.isdigit() or c == ".")
try:
return float(cleaned)
except ValueError:
return None
def check_stock(soup, selector: str) -> bool:
"""Check if product is in stock."""
if not selector:
return True
el = soup.select_one(selector)
if not el:
return False
text = el.get_text(strip=True).lower()
return "in stock" in text or "available" in text
# Site-specific selector configurations
SITE_SELECTORS = {
"amazon.com": {
"price": "span.a-price-whole",
"stock": "#availability span",
"currency": "USD",
},
"walmart.com": {
"price": "[data-testid='price-wrap'] span.f2",
"stock": "[data-testid='fulfillment-badge']",
"currency": "USD",
},
"target.com": {
"price": "[data-test='product-price']",
"stock": "[data-test='fulfillmentSection']",
"currency": "USD",
},
}İzleme Programır
import schedule
import threading
from collections import defaultdict
class PriceMonitor:
def __init__(self, db_connection):
self.db = db_connection
self.price_history = defaultdict(list)
def add_product(self, url: str, site: str, check_interval_minutes: int = 60):
"""Register a product for monitoring."""
selectors = SITE_SELECTORS.get(site, {})
def check():
result = scrape_price(url, selectors)
self.price_history[url].append(result)
self.store_result(result)
self.check_alerts(url, result)
time.sleep(random.uniform(1, 3))
schedule.every(check_interval_minutes).minutes.do(check)
def store_result(self, result: PriceResult):
"""Store price result in database."""
# Insert into price_history table
self.db.execute(
"INSERT INTO price_history (url, price, currency, in_stock, scraped_at) "
"VALUES (%s, %s, %s, %s, %s)",
(result.url, result.price, result.currency,
result.in_stock, result.scraped_at)
)
def check_alerts(self, url: str, result: PriceResult):
"""Check if price change triggers an alert."""
history = self.price_history[url]
if len(history) < 2:
return
prev = history[-2]
curr = history[-1]
if prev.price and curr.price:
change_pct = ((curr.price - prev.price) / prev.price) * 100
if abs(change_pct) >= 5: # 5% threshold
self.send_alert(url, prev.price, curr.price, change_pct)
# Stock status change
if prev.in_stock and not curr.in_stock:
self.send_alert(url, msg="Product went out of stock")
elif not prev.in_stock and curr.in_stock:
self.send_alert(url, msg="Product back in stock")
def send_alert(self, url, old_price=None, new_price=None,
change_pct=None, msg=None):
"""Send price change notification."""
if msg:
print(f"ALERT [{url}]: {msg}")
else:
direction = "dropped" if change_pct < 0 else "increased"
print(f"ALERT [{url}]: Price {direction} {abs(change_pct):.1f}% "
f"(${old_price} -> ${new_price})")
def run(self):
"""Start the monitoring loop."""
while True:
schedule.run_pending()
time.sleep(1)
# Usage
if __name__ == "__main__":
monitor = PriceMonitor(db_connection=None) # Replace with actual DB
# Monitor competitor products
monitor.add_product(
"https://www.amazon.com/dp/B0CHX3QBCH",
site="amazon.com",
check_interval_minutes=60,
)
monitor.add_product(
"https://www.amazon.com/dp/B0D5BKRY4R",
site="amazon.com",
check_interval_minutes=30, # Higher priority
)
monitor.run()Node.js Uygulama
Node.js kullanan takımlar için, burada eşdeğer bir izleme kurulumu ProxyHat's Node SDK.
const axios = require("axios");
const cheerio = require("cheerio");
const { HttpsProxyAgent } = require("https-proxy-agent");
const cron = require("node-cron");
const PROXY_URL = "http://USERNAME:PASSWORD@gate.proxyhat.com:8080";
const agent = new HttpsProxyAgent(PROXY_URL);
const USER_AGENTS = [
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/124.0.0.0 Safari/537.36",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 Chrome/124.0.0.0 Safari/537.36",
];
async function scrapePrice(url, selectors) {
try {
const { data } = await axios.get(url, {
httpsAgent: agent,
headers: {
"User-Agent": USER_AGENTS[Math.floor(Math.random() * USER_AGENTS.length)],
"Accept-Language": "en-US,en;q=0.9",
},
timeout: 30000,
});
const $ = cheerio.load(data);
const priceText = $(selectors.price).first().text().trim();
const price = parseFloat(priceText.replace(/[^0-9.]/g, "")) || null;
return {
url,
price,
currency: selectors.currency || "USD",
inStock: $(selectors.stock).text().toLowerCase().includes("in stock"),
scrapedAt: new Date().toISOString(),
};
} catch (err) {
return { url, price: null, currency: null, inStock: false, scrapedAt: new Date().toISOString() };
}
}
class PriceMonitor {
constructor() {
this.products = [];
this.history = new Map();
}
addProduct(url, selectors, cronExpression = "0 * * * *") {
this.products.push({ url, selectors, cronExpression });
this.history.set(url, []);
cron.schedule(cronExpression, async () => {
const result = await scrapePrice(url, selectors);
const prev = this.history.get(url);
prev.push(result);
if (prev.length >= 2) {
const last = prev[prev.length - 2];
if (last.price && result.price) {
const changePct = ((result.price - last.price) / last.price) * 100;
if (Math.abs(changePct) >= 5) {
console.log(`ALERT [${url}]: Price changed ${changePct.toFixed(1)}%`);
}
}
}
console.log(`Checked ${url}: $${result.price} (${result.inStock ? "in stock" : "out of stock"})`);
});
}
}
// Usage
const monitor = new PriceMonitor();
monitor.addProduct(
"https://www.amazon.com/dp/B0CHX3QBCH",
{ price: "span.a-price-whole", stock: "#availability span", currency: "USD" },
"0 * * * *" // Every hour
);
monitor.addProduct(
"https://www.amazon.com/dp/B0D5BKRY4R",
{ price: "span.a-price-whole", stock: "#availability span", currency: "USD" },
"*/30 * * * *" // Every 30 minutes
);Data Storage and Analysis
Raw fiyat verileri, trendleri zamanında analiz edebileceğinizde değerli olur.
Database Schema
CREATE TABLE monitored_products (
id SERIAL PRIMARY KEY,
url TEXT NOT NULL,
site VARCHAR(100) NOT NULL,
product_name VARCHAR(500),
our_sku VARCHAR(100),
check_interval_minutes INT DEFAULT 60,
is_active BOOLEAN DEFAULT true,
created_at TIMESTAMPTZ DEFAULT now()
);
CREATE TABLE price_history (
id SERIAL PRIMARY KEY,
product_id INT REFERENCES monitored_products(id),
price DECIMAL(10, 2),
currency VARCHAR(3) DEFAULT 'USD',
in_stock BOOLEAN,
scraped_at TIMESTAMPTZ NOT NULL,
created_at TIMESTAMPTZ DEFAULT now()
);
CREATE INDEX idx_price_history_product_time
ON price_history (product_id, scraped_at DESC);Fiyat Trend Queries
-- Average daily price for the last 30 days
SELECT
date_trunc('day', scraped_at) AS day,
AVG(price) AS avg_price,
MIN(price) AS min_price,
MAX(price) AS max_price
FROM price_history
WHERE product_id = 1
AND scraped_at >= now() - INTERVAL '30 days'
GROUP BY day
ORDER BY day;
-- Products with price drops > 10% in the last 24 hours
SELECT
mp.product_name,
mp.url,
old_prices.avg_price AS price_yesterday,
new_prices.avg_price AS price_today,
((new_prices.avg_price - old_prices.avg_price) / old_prices.avg_price * 100) AS change_pct
FROM monitored_products mp
JOIN LATERAL (
SELECT AVG(price) AS avg_price
FROM price_history
WHERE product_id = mp.id
AND scraped_at BETWEEN now() - INTERVAL '48 hours' AND now() - INTERVAL '24 hours'
) old_prices ON true
JOIN LATERAL (
SELECT AVG(price) AS avg_price
FROM price_history
WHERE product_id = mp.id
AND scraped_at >= now() - INTERVAL '24 hours'
) new_prices ON true
WHERE ((new_prices.avg_price - old_prices.avg_price) / old_prices.avg_price * 100) < -10;Uyarı ve Bildirimler
Otomatik uyarılar, fiyat değişikliklerine hızlı tepki vermenizi sağlar. Ortak bildirim kanalları şunları içerir:
- Slack webhooks: Takım çapında görünürlük için ideal. Fiyat değişikliği ayrıntıları ile yapılandırılmış mesajlar gönderin.
- E-posta kaynakları: Günlük veya saatlik olarak tüm fiyat değişikliklerinden eşiğiniz üzerinde.
- Webhook çağrıları: Fiyatlar değiştiğinde repricing motorunu veya diğer otomasyonunuzu sorgulayın.
- Dashboard: Tüm takip edilen ürünlerdeki fiyat eğilimlerinin gerçek zamanlı görselleştirmesi.
Uyarı Thresholds
Farklı senaryolar için farklı uyarı eşlerini yapılandırın:
| Scenario | Threshold | Eylem |
|---|---|---|
| Rakip fiyat düşer >% 5 | % 5 | Slack Bildirim |
| Rakip fiyat düşer >% 15 | % 15 | Fiyatlama ekibi + otomatik fiyat |
| Ürün stok dışına çıkıyor | Stok değişimi | Fırsat uyarısı |
| Aşağıdaki MAP | Aşağıda MAP değer | Uyum uyarısı |
Proxy Best Practices for monitoring
Sürekli izleme, bir kez hurdalığa kıyasla proxy yönetimi için eşsiz zorluklar yaratır.
- Dağcılık zamanla talep eder: Gece yarısı tüm 10.000 ürünlerini kontrol etmek yerine, tüm aralıkta kontroller yay. Bu sürekli, düşük profilli bir istek modeli yaratır.
- Ev sahibi kullanın: Konut temsilcileri Uzun süreli izleme için önemlidir, çünkü aynı veri merkezi IPs günlük aynı siteleri vuracaktır.
- Maç geo-location: Bölgesel fiyatlandırmayı takip ederken, hedef bölgeden proxy kullanın. Bir ABD IP, Alman fiyatlarının yanlış verileri görecek veya yönlendirilecektir.
- Yavaş yavaş başarısızlıklar: Bir istek başarısız olursa, hemen yeniden sorgulanmak yerine üstel geri dönüş ile tekrar deneyin. Başarı oranını izleyin ve düşerse tebrikyi azaltın.
- Cache ve deduplicate: Bir fiyat değişmediyse, tekrarlanan bir kayıt saklayın. Bu veritabanınızı yalın tutar ve analizleri daha hızlı yapar.
Key takeaway: Fiyat izleme bir maraton, bir sprint değil. Sisteminizi sürekli olarak tasarlayın, sürdürülebilir istek kalıpları patlamadan ziyade.
Scaling Your monitoring System
Ürün katalogunuz büyüdükçe, ölçeklendirme kritik hale gelir. İşte bu çalışmanın desenleri:
- Worker havuzu: Bir iş kuyruğundan gelen birden fazla işçi kullanın (Redis, TavşanMQ). Her işçinin kendi proxy bağlantıları vardır ve bağımsız olarak çalışır.
- Öncekilik kuyrukları: Yüksek değerli ürünler ilk ve daha sık kontrol edilir. Low-priority öğeleri kalan kapasiteyi doldurur.
- Adaptif planlama: Bir ürünün fiyatı 7 günde değişmediyse, kontrol frekansı otomatik olarak azaltır. Bugün iki kez değiştiyse, frekansı artırmak.
- Site başına limit: Her hedef sitesinin oranı sınırlarına saygı gösterin. Amazon, Walmart ve niş mağazaların hepsi farklı toleranslara sahiptir.
Daha fazla ölçeklendirme işlemleri için rehberimizi kontrol edin Web için en iyi proxy 2026 ve keşfedin ProxyHat'ın fiyatlandırma planları Yüksek hacimli izleme için.
Key Takeaways
- Otomatik fiyat izleme sağlam bir mimari gerektirir: URL yöneticisi, yedek motor, veri mağazası ve uyarı sistemi.
- per-request rotasyonu ile ev sahipleri bloklar olmadan sürekli izleme için önemlidir.
- Program öncelikliliğe dayanan kontroller - tüm ürünlerin saat izlemesine gerek yoktur.
- Trend analizi için zaman serisi dostu bir şemadaki mağaza fiyat tarihi.
- Kıvrık uyarı eşleri gürültü azaltımı ile dengelemek için bağlanır.
- Dağcılık, sürdürülebilir, düşük profilli bir desen için zaman içinde bile talep eder.
Fiyat izleme sisteminizi oluşturmaya hazır mısın? Başlangıç ProxyHat'ın konut temsilcileri ve oku e-ticaret kılavuzluk Tam strateji için. Teknik uygulama detayları için rehberlerimizi bakınız Python'daki referansları ve Node.js'deki referansları.






