import puppeteer from 'puppeteer'; import fs from 'fs'; async function sleep(ms: number): Promise { return new Promise(resolve => setTimeout(resolve, ms)); } async function main() { 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 }); console.log('Loading page first to establish session...\n'); await page.goto('https://shop.bestdispensary.com/shop', { waitUntil: 'networkidle2', timeout: 60000 }); await sleep(3000); // Bypass age gate const ageGate = await page.$('[data-testid="age-gate-modal"]'); if (ageGate) { console.log('Bypassing age gate...'); const btn = await page.$('[data-testid="age-gate-submit-button"]'); if (btn) await btn.click(); await sleep(3000); } // Wait for page to fully load await sleep(2000); console.log('\nMaking fetch request from page context...\n'); // Try to make the ES request from within page context const result = await page.evaluate(async () => { const url = 'https://search-kyrok9udlk.gapcommerceapi.com/product/search'; const apiKey = 'V3jHL9dFzi3Gj4UISM4lr38Nm0GSxcps5OBz1PbS'; const query = { from: 0, size: 1000, query: { bool: { must: [ { bool: { filter: { range: { customMinPrice: { gte: 0.01, lte: 500000 }}}}}, { bool: { should: [{ match: { isAboveThreshold: true }}]}}, { bool: { should: [{ match: { isHideFromMenu: false }}]}} ] } } }; try { const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json', 'x-api-key': apiKey, }, body: JSON.stringify(query), credentials: 'include', }); if (!response.ok) { return { error: 'HTTP ' + response.status, statusText: response.statusText }; } const data = await response.json(); return { total: data.hits?.total?.value, count: data.hits?.hits?.length, firstProduct: data.hits?.hits?.[0]?._source, products: data.hits?.hits?.map((h: any) => h._source), }; } catch (err: any) { return { error: err.message }; } }); if (result.error) { console.log('Error: ' + result.error); if (result.statusText) console.log('Status: ' + result.statusText); } else { console.log('Total products in ES: ' + result.total); console.log('Products returned: ' + result.count); if (result.firstProduct) { console.log('\n=== PRODUCT FIELDS ===\n'); console.log(Object.keys(result.firstProduct).sort().join('\n')); console.log('\n=== SAMPLE PRODUCT ===\n'); console.log(JSON.stringify(result.firstProduct, null, 2)); // Save all products if (result.products) { fs.writeFileSync('/tmp/treez-all-products.json', JSON.stringify(result.products, null, 2)); console.log('\nSaved ' + result.products.length + ' products to /tmp/treez-all-products.json'); } } } await browser.close(); } main();