feat: launch a lazy per-run browser for the fallback scraper

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013gwc3aCiyQxmCWQke8RvEz
This commit is contained in:
Sjoerd de Vries
2026-09-05 17:39:03 +02:00
parent 358347e8ba
commit fc8dadc8a3
+22 -2
View File
@@ -8,6 +8,7 @@ const {
recordCheckSuccess, recordCheckFailure, recordCheckSuccess, recordCheckFailure,
} = require('./src/db'); } = require('./src/db');
const { fetchAndExtractPrice } = require('./src/scraper'); const { fetchAndExtractPrice } = require('./src/scraper');
const { launchBrowser, fetchAndExtractPriceViaBrowser } = require('./src/browserScraper');
const { createTransport, sendPriceChangeEmail } = require('./src/mailer'); const { createTransport, sendPriceChangeEmail } = require('./src/mailer');
const { checkAllProducts } = require('./src/checkProducts'); const { checkAllProducts } = require('./src/checkProducts');
const { start: startScheduler } = require('./src/scheduler'); const { start: startScheduler } = require('./src/scheduler');
@@ -36,10 +37,22 @@ function summarize(results) {
return parts.length > 0 ? parts.join(' ') : 'geen producten'; return parts.length > 0 ? parts.join(' ') : 'geen producten';
} }
function runCheck() { async function runCheck() {
const products = listProducts(db); const products = listProducts(db);
let browserPromise = null;
function getBrowser() {
if (!browserPromise) {
browserPromise = launchBrowser();
}
return browserPromise;
}
try {
const deps = { const deps = {
fetchAndExtractPrice, fetchAndExtractPrice,
fetchAndExtractPriceViaBrowser: async (url) => {
const browser = await getBrowser();
return fetchAndExtractPriceViaBrowser(browser, url);
},
sendMail: (payload) => sendPriceChangeEmail(transport, { sendMail: (payload) => sendPriceChangeEmail(transport, {
from: process.env.SMTP_FROM, from: process.env.SMTP_FROM,
to: process.env.NOTIFY_EMAIL, to: process.env.NOTIFY_EMAIL,
@@ -49,11 +62,18 @@ function runCheck() {
recordCheckSuccess: (id, data) => recordCheckSuccess(db, id, data), recordCheckSuccess: (id, data) => recordCheckSuccess(db, id, data),
now: () => new Date().toISOString(), now: () => new Date().toISOString(),
}; };
return checkAllProducts(products, deps).then((results) => { const results = await checkAllProducts(products, deps);
console.log(`[check] ${products.length} product(en) gecontroleerd: ${summarize(results)}`); console.log(`[check] ${products.length} product(en) gecontroleerd: ${summarize(results)}`);
return results; return results;
} finally {
if (browserPromise) {
const browser = await browserPromise;
await browser.close().catch((err) => {
console.error(`[check] kon de browser niet netjes sluiten: ${err && err.message}`);
}); });
} }
}
}
startScheduler(runCheck); startScheduler(runCheck);