Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 91 additions & 0 deletions examples/scraperDemo.js
Original file line number Diff line number Diff line change
@@ -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(`
<h2>Power BI Scraper Demo</h2>
<form method="POST" action="/scrape">
<label>Enter Dashboard URL with Auth Token:</label><br/>
<input type="text" name="url" style="width: 90%;" required /><br/><br/>
<button type="submit">Scrape</button>
</form>
`);
});

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("<p>No 'query' XHR requests found.</p>");
}

// Display results
const html = `
<h2>Found ${scrapedQueries.length} Query Requests</h2>
${scrapedQueries
.map(
(q, i) => `
<details>
<summary><strong>[${i + 1}]</strong> ${q.url}</summary>
<pre>${JSON.stringify(q.data, null, 2)}</pre>
</details>
`
)
.join('')}
<br/><a href="/">🔙 Back</a>
`;

res.send(html);
});

app.listen(PORT, () => {
console.log(`🧪 Scraper running at http://localhost:${PORT}`);
});
25 changes: 25 additions & 0 deletions examples/scraperDemo.md
Original file line number Diff line number Diff line change
@@ -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 <http://localhost:3000>, 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.