Hazır Kod: Çoklu Ürün Fiyat Takip Botu (10+ Farklı Ürünü Sırayla Gezen Dizi Mimarisi) -
Önceki rehberimizde tek bir ürün linkini kontrol eden yapıyı kurmuştuk. Ancak gerçek hayatta takip etmek istediğimiz birden fazla ürün (ekran kartı, monitör, kahve makinesi, telefon vb.) olur.
Her ürün için ayrı bir script çalıştırmak RAM'i tüketir. Doğru mühendislik yaklaşımı:
Bu rehberde siteler tarafından engellenmemek (IP ban yememek) için aralara rastgele gecikmeler koyan çoklu takip mimarisini paylaşıyorum.
Kod:
const puppeteer = require('puppeteer');
const axios = require('axios');
// --- TELEGRAM AYARLARI ---
const TELEGRAM_BOT_TOKEN = 'BURAYA_BOT_TOKEN';
const TELEGRAM_CHAT_ID = 'BURAYA_CHAT_ID';
// Kaç dakikada bir tüm liste baştan kontrol edilsin?
const KONTROL_PERIYODU_DAKIKA = 45;
// --- TAKİP EDİLECEK ÜRÜNLER LİSTESİ ---
// Her ürünün adını, linkini, hedef fiyatını ve sitenin fiyat etiketini (selector) buraya ekleyin
const URUNLER = [
{
isim: 'ASUS RTX 4070 Ti Ekran Kartı',
url: 'https://www.ornek-site.com/asus-rtx-4070-ti-p-12345',
hedefFiyat: 32000,
selector: '.product-price, [data-test-id="price-current-price"]'
},
{
isim: 'Samsung 27" 2K 165Hz Monitör',
url: 'https://www.ornek-site.com/samsung-27-monitor-p-67890',
hedefFiyat: 8500,
selector: '.product-price, .current-price-box'
},
{
isim: 'Philips Airfryer XXL',
url: 'https://www.ornek-site.com/philips-airfryer-xxl-p-55443',
hedefFiyat: 5200,
selector: '.price, .product-price-current'
},
{
isim: 'Sony WH-1000XM5 Kulaklık',
url: 'https://www.ornek-site.com/sony-wh1000xm5-p-99881',
hedefFiyat: 11500,
selector: '.price'
}
];
// İnsansı rastgele bekleme fonksiyonu (ms)
const bekle = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
async function telegramBildir(mesaj) {
const url = `https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage`;
try {
await axios.post(url, {
chat_id: TELEGRAM_CHAT_ID,
text: mesaj,
parse_mode: 'HTML',
disable_web_page_preview: false
});
} catch (err) {
console.error('Telegram hata:', err.message);
}
}
function fiyatiSayiyaCevir(fiyatMetni) {
if (!fiyatMetni) return null;
const temiz = fiyatMetni
.replace(/[^\d,\.]/g, '')
.replace(/\./g, '')
.replace(',', '.');
return parseFloat(temiz);
}
/**
* Tüm ürünleri tek bir tarayıcı oturumunda sırayla gezen ana döngü
*/
async function tumListeyiKontrolEt() {
console.log(`\n==================================================`);
console.log(`[${new Date().toLocaleTimeString('tr-TR')}] Toplam ${URUNLER.length} ürün taranıyor...`);
console.log(`==================================================`);
let browser = null;
try {
browser = await puppeteer.launch({
headless: 'new',
args: [
'--no-sandbox',
'--disable-setuid-sandbox',
'--disable-dev-shm-usage',
'--disable-gpu'
]
});
const page = await browser.newPage();
await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36');
// Resimleri ve gereksiz medya isteklerini engelleyerek hızı 4 katına çıkarın
await page.setRequestInterception(true);
page.on('request', (req) => {
if (['image', 'font', 'media'].includes(req.resourceType())) {
req.abort();
} else {
req.continue();
}
});
// Ürünleri sırayla gez
for (let i = 0; i < URUNLER.length; i++) {
const urun = URUNLER[i];
console.log(`\n[${i + 1}/${URUNLER.length}] İnceleniyor: ${urun.isim}`);
try {
await page.goto(urun.url, { waitUntil: 'domcontentloaded', timeout: 35000 });
// Sayfadaki fiyat bilgisini oku
const cekilenFiyatMetni = await page.evaluate((secici) => {
const eleman = document.querySelector(secici);
return eleman ? eleman.innerText.trim() : null;
}, urun.selector);
if (!cekilenFiyatMetni) {
console.log(`⚠️ Fiyat etiketi bulunamadı! Sayfa yapısı değişmiş veya bot engeli olabilir.`);
continue;
}
const guncelFiyat = fiyatiSayiyaCevir(cekilenFiyatMetni);
console.log(`Güncel: ${guncelFiyat} TL | Hedef: ${urun.hedefFiyat} TL`);
// Hedef fiyat kontrolü
if (guncelFiyat && guncelFiyat <= urun.hedefFiyat) {
console.log(`? İNDİRİM YAKALANDI! Telegram'a gönderiliyor...`);
const alarm = `
? <b>İNDİRİM YAKALANDI!</b> ?
━━━━━━━━━━━━━━━━━━━━
? <b>Ürün:</b> ${urun.isim}
? <b>Hedef Fiyat:</b> ${urun.hedefFiyat} TL
? <b>GÜNCEL FİYAT:</b> <b>${guncelFiyat} TL</b>
⏰ <b>Saat:</b> ${new Date().toLocaleTimeString('tr-TR')}
━━━━━━━━━━━━━━━━━━━━
? <a href="${urun.url}">Hemen Ürüne Git</a>
`;
await telegramBildir(alarm);
} else {
console.log(`Fiyat henüz istenen seviyede değil.`);
}
} catch (urunHatasi) {
console.error(`"${urun.isim}" kontrol edilirken hata:`, urunHatasi.message);
}
// Sitenin bot olduğumuzu anlamaması için iki ürün arasında 3-6 saniye rastgele bekle
const beklemeSuresi = Math.floor(Math.random() * 3000) + 3000;
await bekle(beklemeSuresi);
}
} catch (genelHata) {
console.error('Genel tarama hatası:', genelHata.message);
} finally {
if (browser) {
await browser.close();
console.log(`\nTarama tamamlandı, tarayıcı kapatıldı. Bir sonraki kontrol ${KONTROL_PERIYODU_DAKIKA} dakika sonra.`);
}
}
}
// İlk çalıştırma
tumListeyiKontrolEt();
// Belirlenen periyotta sürekli çalış
setInterval(tumListeyiKontrolEt, KONTROL_PERIYODU_DAKIKA * 60 * 1000);