Initial commit
commit
bcdd389edf
@ -0,0 +1 @@
|
||||
/node_modules/
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"printWidth": 140,
|
||||
"singleQuote": true,
|
||||
"semi": true,
|
||||
"useTabs": true
|
||||
}
|
||||
@ -0,0 +1 @@
|
||||
For annoying RSS channels that have bot protection and thus cannot be subscribed to.
|
||||
@ -0,0 +1,57 @@
|
||||
// xml-proxy.js
|
||||
import express from 'express';
|
||||
import puppeteer from 'puppeteer-extra';
|
||||
import StealthPlugin from 'puppeteer-extra-plugin-stealth';
|
||||
import he from 'he'; // HTML entity decoder
|
||||
|
||||
puppeteer.use(StealthPlugin());
|
||||
|
||||
const app = express();
|
||||
const PORT = process.env.PORT || 3000;
|
||||
const PASSWORD = process.env.PASSWORD || '8yug8976tyu7654etdr645etr65etrdyugydt';
|
||||
|
||||
app.get('/fetch', async (req, res) => {
|
||||
const { url, password } = req.query;
|
||||
if (password !== PASSWORD) {
|
||||
res.status(403);
|
||||
res.send('Missing password');
|
||||
return;
|
||||
}
|
||||
if (!url) return res.status(400).send('Missing url parameter');
|
||||
|
||||
let browser;
|
||||
try {
|
||||
browser = await puppeteer.launch({
|
||||
headless: true,
|
||||
args: ['--no-sandbox', '--disable-setuid-sandbox'],
|
||||
});
|
||||
|
||||
const page = await browser.newPage();
|
||||
|
||||
await page.setUserAgent(
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36',
|
||||
);
|
||||
|
||||
await page.goto(url, { waitUntil: 'networkidle2' });
|
||||
|
||||
// Extract escaped XML from <pre> and decode
|
||||
const xml = await page.evaluate(() => {
|
||||
const pre = document.querySelector('pre');
|
||||
return pre ? pre.innerHTML : document.documentElement.outerHTML;
|
||||
});
|
||||
|
||||
const decodedXml = he.decode(xml);
|
||||
|
||||
res.set('Content-Type', 'application/xml; charset=utf-8');
|
||||
res.send(decodedXml);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
res.status(500).send('Error fetching XML');
|
||||
} finally {
|
||||
if (browser) await browser.close();
|
||||
}
|
||||
});
|
||||
|
||||
app.listen(PORT, () => {
|
||||
console.log(`XML Puppeteer proxy listening at http://localhost:${PORT}`);
|
||||
});
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "rss-proxy",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.mjs",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"express": "^5.2.1",
|
||||
"he": "^1.2.0",
|
||||
"puppeteer": "^24.36.1",
|
||||
"puppeteer-extra": "^3.3.6",
|
||||
"puppeteer-extra-plugin-stealth": "^2.11.2"
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue