Refactor price monitoring to work exclusively with ceneo.pl, removing unused selectors and browser automation. Update product comparison logic to match by name and include shop information in notifications.

This commit is contained in:
Norbert Maciaszek
2025-11-16 18:40:36 +01:00
parent 1f41be62f1
commit 72ba9aae20
2 changed files with 180 additions and 83 deletions

153
index.js.old Normal file
View File

@@ -0,0 +1,153 @@
const cheerio = require("cheerio");
const cron = require("node-cron");
const axios = require("axios");
const { chromium } = require("playwright");
const fs = require("fs");
const discordWebhook =
"https://discord.com/api/webhooks/1439286509390921749/t2Hb8XloF6zhDRYD1yh_QlkHHa9eHUyXvd9TxZRHwqR_b_OxxbnwDgsm4em8TwA9NQIa";
const priceSelectors = {
miodowamydlarnia: ".projector_prices__price",
greentouch: ".main-price",
amazon: "#corePrice_feature_div .a-price .a-offscreen",
soxo: "#projector_price_value span",
empik: '[data-ta-section="priceMainContainer"] [data-ta="price"]',
notino: "#pd-price",
};
const excludePage = ["allegro", "homla.com.pl", "home-you.com"];
function sendMessage(message) {
axios.post(discordWebhook, {
content: message,
});
}
async function compareAndSave(productsPrice) {
if (!fs.existsSync("productsPrice.json")) {
fs.writeFileSync("productsPrice.json", "[]");
}
const productsPriceJson = fs.readFileSync("productsPrice.json", "utf8");
const oldProductsPrice = JSON.parse(productsPriceJson);
const diffProducts = [];
for (const product of productsPrice) {
const oldProduct = oldProductsPrice.find(
(oldProduct) => oldProduct.link === product.link
);
if (oldProduct && oldProduct.price !== product.price) {
diffProducts.push({
name: product.name,
newPrice: product.price,
oldPrice: oldProduct.price,
link: product.link,
});
}
}
for (const product of diffProducts) {
sendMessage(
`Zmiana ceny **${product.name}**:\nCena: ${product.oldPrice} -> ${product.newPrice}\nLink: ${product.link}`
);
}
if (diffProducts.length === 0) {
sendMessage("Brak zmian w cenach");
}
fs.writeFileSync(
"productsPrice.json",
JSON.stringify(productsPrice, null, 2)
);
}
async function getProducts() {
const products = await axios
.get(
"https://db.maciaszek.ovh/api/collections/gifts_items/records?fields=title,link"
)
.then((response) => response.data.items);
return products
.filter((product) => product.link !== "")
.filter(
(product) => !excludePage.some((page) => product.link.includes(page))
);
}
async function init() {
const productsWithLinks = await getProducts();
const productsWithBrowser = [];
const productsPrice = [];
const selectors = Object.keys(priceSelectors);
console.log("Zaczynam sprawdzać ceny");
for (const product of productsWithLinks) {
if (product.link === "") continue;
try {
const { data } = await axios.get(product.link, {
headers: {
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0 Safari/537.36",
},
});
const $ = cheerio.load(data);
const selector = selectors.find((selector) =>
product.link.includes(selector)
);
const price = $(priceSelectors[selector]).text();
productsPrice.push({
name: product.title,
price: price,
link: product.link,
});
} catch {
productsWithBrowser.push(product);
}
}
if (productsWithBrowser.length > 0) {
const browser = await chromium.launch();
const context = await browser.newContext({
userAgent:
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0 Safari/537.36",
});
const page = await context.newPage();
for (const product of productsWithBrowser) {
await page.goto(product.link);
const selector = selectors.find((selector) =>
product.link.includes(selector)
);
const element = await page.$(priceSelectors[selector]);
if (!element) continue;
const price = await element.textContent();
productsPrice.push({
name: product.title,
price: price,
link: product.link,
});
}
await browser.close();
}
await compareAndSave(productsPrice);
console.log("Sprawdzone! Aktualne ceny zapisane w productsPrice.json");
}
sendMessage("Zaczynam monitoring cen");
const task = cron.schedule("0 6,9,12,15,18,21 * * *", init, {
timezone: "Europe/Warsaw",
});
task.execute();