/** * Detailed brand section analysis */ import puppeteer, { Page } from 'puppeteer'; const STORE_ID = 'best'; async function sleep(ms: number): Promise { return new Promise(resolve => setTimeout(resolve, ms)); } async function bypassAgeGate(page: Page): Promise { const ageGate = await page.$('[data-testid="age-gate-modal"]'); if (ageGate) { console.log(' Age gate detected, bypassing...'); const btn = await page.$('[data-testid="age-gate-submit-button"]'); if (btn) await btn.click(); await sleep(2000); } } async function main() { console.log('='.repeat(60)); console.log('Detailed Brand Section Analysis'); console.log('='.repeat(60)); const browser = await puppeteer.launch({ headless: true, args: ['--no-sandbox', '--disable-setuid-sandbox'], }); const page = await browser.newPage(); await page.setViewport({ width: 1920, height: 1080 }); await page.setRequestInterception(true); page.on('request', (req) => { if (['image', 'font', 'media'].includes(req.resourceType())) { req.abort(); } else { req.continue(); } }); const url = `https://${STORE_ID}.treez.io/onlinemenu/brands?customerType=ADULT`; console.log(`\nNavigating to ${url}`); await page.goto(url, { waitUntil: 'networkidle2', timeout: 60000 }); await sleep(3000); await bypassAgeGate(page); await sleep(2000); // Scroll multiple times to load all content console.log('\n[1] Scrolling to load all content...'); let previousHeight = 0; let scrollCount = 0; for (let i = 0; i < 30; i++) { await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight)); await sleep(1500); const currentHeight = await page.evaluate(() => document.body.scrollHeight); const productCount = await page.evaluate(() => document.querySelectorAll('a[href*="/product/"]').length ); console.log(` Scroll ${i + 1}: height=${currentHeight}, products=${productCount}`); if (currentHeight === previousHeight) { scrollCount++; if (scrollCount >= 3) break; } else { scrollCount = 0; } previousHeight = currentHeight; } // Look at ALL h2/h3 headers on page console.log('\n[2] Finding ALL h2/h3 headers on page...'); const headers = await page.evaluate(() => { const results: { tag: string; text: string; parentClass: string }[] = []; document.querySelectorAll('h2, h3').forEach((el: Element) => { results.push({ tag: el.tagName, text: el.textContent?.trim().slice(0, 80) || '', parentClass: el.parentElement?.className?.slice(0, 50) || '', }); }); return results; }); console.log(`Found ${headers.length} headers:`); headers.forEach((h: { tag: string; text: string }) => console.log(` [${h.tag}] "${h.text}"`) ); // Get products grouped by their section heading console.log('\n[3] Getting products per section...'); const sectionProducts = await page.evaluate(() => { const results: { heading: string; products: number }[] = []; // Find all sections that contain products document.querySelectorAll('[class*="products_product__section"]').forEach((section: Element) => { const heading = section.querySelector('h2, h3'); const headingText = heading?.textContent?.trim() || 'Unknown'; const products = section.querySelectorAll('a[href*="/product/"]'); results.push({ heading: headingText, products: products.length, }); }); return results; }); console.log(`Found ${sectionProducts.length} brand sections:`); let totalProducts = 0; sectionProducts.forEach((s: { heading: string; products: number }) => { console.log(` ${s.heading}: ${s.products} products`); totalProducts += s.products; }); console.log(`\nTotal products across all sections: ${totalProducts}`); // Also extract brand from each product's URL/card console.log('\n[4] Extracting brand from product URLs/cards...'); const brandCounts = await page.evaluate(() => { const byBrand: Record = {}; const seen = new Set(); document.querySelectorAll('a[href*="/product/"]').forEach((a: Element) => { const href = a.getAttribute('href') || ''; const img = a.querySelector('img'); const name = img?.getAttribute('alt') || ''; if (!name || seen.has(name)) return; seen.add(name); // Try to find brand from the card const brandEl = a.querySelector('[class*="brand"], [class*="Brand"], span, p'); let brand = ''; // Try various methods to find brand const allSpans = a.querySelectorAll('span, p'); allSpans.forEach((span: Element) => { const text = span.textContent?.trim() || ''; if (text && text.length < 50 && text !== name && !text.includes('$')) { if (!brand) brand = text; } }); // Fallback: get brand from parent section heading if (!brand) { const section = a.closest('[class*="products_product__section"]'); const heading = section?.querySelector('h2, h3'); brand = heading?.textContent?.trim() || 'Unknown'; } byBrand[brand] = (byBrand[brand] || 0) + 1; }); return byBrand; }); console.log('Products by brand:'); Object.entries(brandCounts) .sort((a, b) => (b[1] as number) - (a[1] as number)) .forEach(([brand, count]) => { console.log(` ${brand}: ${count}`); }); const uniqueTotal = Object.values(brandCounts).reduce((sum: number, c) => sum + (c as number), 0); console.log(`\nTotal unique products: ${uniqueTotal}`); await browser.close(); } main().catch(console.error);