it's now a functional backend
This commit is contained in:
@@ -1,2 +1,3 @@
|
||||
PORT=3001
|
||||
NIX_CHROMIUM_PATH=<PATH/TO/CHROMIUM/INSIDE/NIX/STORE>
|
||||
ON_NIX="true"
|
||||
|
||||
@@ -1,41 +1,18 @@
|
||||
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 fetch3Bmeteo from './scrapers/3Bmeteo.js'
|
||||
import fetchAeronauticaMilitare from './scrapers/AeronauticaMilitare.js'
|
||||
import fetchOpenMeteo from './scrapers/OpenMeteo.js'
|
||||
import WeatherScraper from './weatherScraper.js'
|
||||
|
||||
const NIX_OPS = {
|
||||
executablePath: process.env.NIX_CHROMIUM_PATH,
|
||||
}
|
||||
const opts = process.env.ON_NIX ? NIX_OPS : {}
|
||||
const scraper = new WeatherScraper()
|
||||
await scraper.init()
|
||||
setInterval(() => scraper.fetch(), 1000 * 60 * 5)
|
||||
|
||||
const run = async () => {
|
||||
const browser = await puppeteer.launch(opts)
|
||||
app.get('/', (req, res) => {
|
||||
res.json(scraper.data)
|
||||
})
|
||||
|
||||
const [
|
||||
// Comment out unwanted fields
|
||||
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 })
|
||||
app.listen(port, () => {
|
||||
console.log(`Weather Scraper listening on port ${port}`)
|
||||
})
|
||||
|
||||
Generated
+1834
-1107
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"dotenv": "^16.4.5",
|
||||
"express": "^4.21.1",
|
||||
"puppeteer": "^23.6.0"
|
||||
},
|
||||
"type": "module"
|
||||
|
||||
+21
-10
@@ -54,7 +54,7 @@ const scrapePage = async (browser, url, isToday) => {
|
||||
|
||||
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
|
||||
|
||||
// if (isToday) {
|
||||
@@ -74,11 +74,11 @@ const scrapePage = async (browser, url, isToday) => {
|
||||
// // console.log(error)
|
||||
// }
|
||||
// }
|
||||
for (let i = startTime; i <= endTime; i++) {
|
||||
for (let i = startTime; i < endTime; i++) {
|
||||
try {
|
||||
const selector = isToday
|
||||
? `.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)
|
||||
|
||||
@@ -102,14 +102,25 @@ const scrapePage = async (browser, url, isToday) => {
|
||||
}
|
||||
|
||||
const rearrangeResults = 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]
|
||||
|
||||
/// I don't know why but for a couple of days iLMeteo had the weather table
|
||||
/// starting at 1am instead of 0am, so I had to grab the midnight (0am)
|
||||
/// from the day before, delete it and put it at the beginning of the
|
||||
/// following day
|
||||
///
|
||||
/// 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
|
||||
|
||||
// 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 => {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user