diff --git a/examples/scraperDemo.js b/examples/scraperDemo.js new file mode 100644 index 0000000000..90547650bd --- /dev/null +++ b/examples/scraperDemo.js @@ -0,0 +1,91 @@ +// scraperDemo.js +const express = require('express'); +const puppeteer = require('puppeteer'); +const bodyParser = require('body-parser'); + +const app = express(); +const PORT = 3000; + +app.use(bodyParser.urlencoded({ extended: true })); + +app.get('/', (req, res) => { + res.send(` +

Power BI Scraper Demo

+
+
+

+ +
+ `); +}); + +app.post('/scrape', async (req, res) => { + const { url } = req.body; + + if (!url || !url.startsWith('http')) { + return res.send('Invalid URL'); + } + + const scrapedQueries = []; + let browser; + + try { + browser = await puppeteer.launch({ headless: 'new' }); + const page = await browser.newPage(); + + // Intercept XHR 'query' responses + page.on('response', async (response) => { + const request = response.request(); + const reqUrl = request.url(); + + if (request.resourceType() === 'xhr' && reqUrl.includes('query')) { + try { + const json = await response.json(); + scrapedQueries.push({ + url: reqUrl, + status: response.status(), + data: json, + }); + } catch (err) { + console.log(`Error reading JSON from ${reqUrl}`); + } + } + }); + + await page.goto(url, { waitUntil: 'networkidle2' }); + await page.waitForTimeout(5000); // Wait for queries to fire + } catch (err) { + if (browser) { + await browser.close(); + } + return res.send(`❌ Error loading page: ${err.message}`); + } + + await browser.close(); + + if (scrapedQueries.length === 0) { + return res.send("

No 'query' XHR requests found.

"); + } + + // Display results + const html = ` +

Found ${scrapedQueries.length} Query Requests

+ ${scrapedQueries + .map( + (q, i) => ` +
+ [${i + 1}] ${q.url} +
${JSON.stringify(q.data, null, 2)}
+
+ ` + ) + .join('')} +
🔙 Back + `; + + res.send(html); +}); + +app.listen(PORT, () => { + console.log(`🧪 Scraper running at http://localhost:${PORT}`); +}); diff --git a/examples/scraperDemo.md b/examples/scraperDemo.md new file mode 100644 index 0000000000..ab8dc0aacd --- /dev/null +++ b/examples/scraperDemo.md @@ -0,0 +1,25 @@ +# Power BI Scraper Demo + +This example shows how to use Express and Puppeteer to capture XHR requests that contain `query` in their URL. The captured JSON payloads are rendered in the browser so you can inspect responses coming from an authenticated dashboard URL. + +## Prerequisites + +- Node.js 18+ +- npm + +## Installation + +```bash +cd examples +npm install express puppeteer body-parser +``` + +## Usage + +```bash +node scraperDemo.js +``` + +Open , paste your dashboard URL (including the auth token), and submit the form. Any `xhr` requests whose URLs contain `query` will be captured and displayed. + +> **Note:** Authentication is handled through the token embedded in the URL—no additional login flow is required.