From fc8dadc8a3fdfc90f403fbb65b020be94605a3f4 Mon Sep 17 00:00:00 2001 From: Sjoerd de Vries Date: Sat, 5 Sep 2026 17:39:03 +0200 Subject: [PATCH] feat: launch a lazy per-run browser for the fallback scraper Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_013gwc3aCiyQxmCWQke8RvEz --- server.js | 48 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/server.js b/server.js index 724f511..f8cd297 100644 --- a/server.js +++ b/server.js @@ -8,6 +8,7 @@ const { recordCheckSuccess, recordCheckFailure, } = require('./src/db'); const { fetchAndExtractPrice } = require('./src/scraper'); +const { launchBrowser, fetchAndExtractPriceViaBrowser } = require('./src/browserScraper'); const { createTransport, sendPriceChangeEmail } = require('./src/mailer'); const { checkAllProducts } = require('./src/checkProducts'); const { start: startScheduler } = require('./src/scheduler'); @@ -36,23 +37,42 @@ function summarize(results) { return parts.length > 0 ? parts.join(' ') : 'geen producten'; } -function runCheck() { +async function runCheck() { const products = listProducts(db); - const deps = { - fetchAndExtractPrice, - sendMail: (payload) => sendPriceChangeEmail(transport, { - from: process.env.SMTP_FROM, - to: process.env.NOTIFY_EMAIL, - ...payload, - }), - recordCheckFailure: (id, status) => recordCheckFailure(db, id, status), - recordCheckSuccess: (id, data) => recordCheckSuccess(db, id, data), - now: () => new Date().toISOString(), - }; - return checkAllProducts(products, deps).then((results) => { + let browserPromise = null; + function getBrowser() { + if (!browserPromise) { + browserPromise = launchBrowser(); + } + return browserPromise; + } + try { + const deps = { + fetchAndExtractPrice, + fetchAndExtractPriceViaBrowser: async (url) => { + const browser = await getBrowser(); + return fetchAndExtractPriceViaBrowser(browser, url); + }, + sendMail: (payload) => sendPriceChangeEmail(transport, { + from: process.env.SMTP_FROM, + to: process.env.NOTIFY_EMAIL, + ...payload, + }), + recordCheckFailure: (id, status) => recordCheckFailure(db, id, status), + recordCheckSuccess: (id, data) => recordCheckSuccess(db, id, data), + now: () => new Date().toISOString(), + }; + const results = await checkAllProducts(products, deps); console.log(`[check] ${products.length} product(en) gecontroleerd: ${summarize(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);