it's now a functional backend

main
Fran314 3 weeks ago
parent 81166a5d49
commit b7fe73c25d

@ -1,2 +1,3 @@
PORT=3001
NIX_CHROMIUM_PATH=<PATH/TO/CHROMIUM/INSIDE/NIX/STORE> NIX_CHROMIUM_PATH=<PATH/TO/CHROMIUM/INSIDE/NIX/STORE>
ON_NIX="true" ON_NIX="true"

@ -1,41 +1,18 @@
import 'dotenv/config' import 'dotenv/config'
import puppeteer from 'puppeteer' import express from 'express'
const app = express()
const port = process.env.PORT || 3000
import fetchILMeteo from './scrapers/iLMeteo.js' import WeatherScraper from './weatherScraper.js'
import fetch3Bmeteo from './scrapers/3Bmeteo.js'
import fetchAeronauticaMilitare from './scrapers/AeronauticaMilitare.js'
import fetchOpenMeteo from './scrapers/OpenMeteo.js'
const NIX_OPS = { const scraper = new WeatherScraper()
executablePath: process.env.NIX_CHROMIUM_PATH, await scraper.init()
} setInterval(() => scraper.fetch(), 1000 * 60 * 5)
const opts = process.env.ON_NIX ? NIX_OPS : {}
const run = async () => { app.get('/', (req, res) => {
const browser = await puppeteer.launch(opts) res.json(scraper.data)
})
const [ app.listen(port, () => {
// Comment out unwanted fields console.log(`Weather Scraper listening on port ${port}`)
iLMeteo, })
treBmeteo,
openMeteo,
aeronauticaMilitare,
] = await Promise.all([
fetchILMeteo(browser),
fetch3Bmeteo(browser),
fetchOpenMeteo(),
fetchAeronauticaMilitare(browser),
])
await browser.close()
return {
iLMeteo,
treBmeteo,
openMeteo,
aeronauticaMilitare,
}
}
const result = await run()
console.dir(result, { depth: null })

2945
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -1,6 +1,7 @@
{ {
"dependencies": { "dependencies": {
"dotenv": "^16.4.5", "dotenv": "^16.4.5",
"express": "^4.21.1",
"puppeteer": "^23.6.0" "puppeteer": "^23.6.0"
}, },
"type": "module" "type": "module"

@ -54,7 +54,7 @@ const scrapePage = async (browser, url, isToday) => {
const weatherTable = await page.locator('.weather_table').waitHandle() const weatherTable = await page.locator('.weather_table').waitHandle()
const startTime = isToday ? new Date().getHours() + 1 : 1 const startTime = isToday ? new Date().getHours() + 1 : 0
const endTime = 24 const endTime = 24
// if (isToday) { // if (isToday) {
@ -74,11 +74,11 @@ const scrapePage = async (browser, url, isToday) => {
// // console.log(error) // // console.log(error)
// } // }
// } // }
for (let i = startTime; i <= endTime; i++) { for (let i = startTime; i < endTime; i++) {
try { try {
const selector = isToday const selector = isToday
? `.forecast_1h[data-dialogid="${i}"] td` ? `.forecast_1h[data-dialogid="${i}"] td`
: `.forecast_1h[data-dialogid="${1000 + i - 1}"] td` : `.forecast_1h[data-dialogid="${1000 + i}"] td`
const fields = await weatherTable.$$(selector) const fields = await weatherTable.$$(selector)
@ -102,14 +102,25 @@ const scrapePage = async (browser, url, isToday) => {
} }
const rearrangeResults = results => { const rearrangeResults = results => {
for (let i = 0; i < 6; i++) { /// I don't know why but for a couple of days iLMeteo had the weather table
const midnight = results[i][24] /// starting at 1am instead of 0am, so I had to grab the midnight (0am)
delete results[i][24] /// from the day before, delete it and put it at the beginning of the
results[i + 1][0] = midnight /// following day
} ///
delete results[6][24] /// EXCEPT now it doesn't do this anymore (like it didn't use to do it
/// before) and I have to skip this rearrangement
///
/// I do NOT understand why weather websites need to change this often
return results return results
// for (let i = 0; i < 6; i++) {
// const midnight = results[i][24]
// delete results[i][24]
// results[i + 1][0] = midnight
// }
// delete results[6][24]
//
// return results
} }
const getDaySummary = day => { const getDaySummary = day => {

@ -0,0 +1,57 @@
import 'dotenv/config'
import puppeteer from 'puppeteer'
import fetchILMeteo from './scrapers/iLMeteo.js'
import fetch3Bmeteo from './scrapers/3Bmeteo.js'
import fetchAeronauticaMilitare from './scrapers/AeronauticaMilitare.js'
import fetchOpenMeteo from './scrapers/OpenMeteo.js'
export default class WeatherScraper {
constructor() {
this.lock = false
this.data = {}
}
async init(opts) {
const NIX_OPS = {
executablePath: process.env.NIX_CHROMIUM_PATH,
}
const OPTS = process.env.ON_NIX ? NIX_OPS : {}
this.browser = await puppeteer.launch(OPTS)
await this.fetch()
}
async fetch() {
const timestamp = new Date().getTime()
if (this.lock) {
console.log(`[${timestamp}] skipped (locked)`)
return
}
this.lock = true
console.log(`[${timestamp}] updating`)
const [
// Comment out unwanted fields
iLMeteo,
treBmeteo,
openMeteo,
aeronauticaMilitare,
] = await Promise.all([
fetchILMeteo(this.browser),
fetch3Bmeteo(this.browser),
fetchOpenMeteo(),
fetchAeronauticaMilitare(this.browser),
])
console.log(`[${timestamp}] updated`)
this.data = {
timestamp,
iLMeteo,
treBmeteo,
openMeteo,
aeronauticaMilitare,
}
this.lock = false
}
}
Loading…
Cancel
Save