You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
128 lines
3.8 KiB
JavaScript
128 lines
3.8 KiB
JavaScript
const parseTemp = el => {
|
|
return parseFloat(el.textContent)
|
|
}
|
|
const parsePrec = el => {
|
|
const text = el.textContent
|
|
if (text === '- assenti -') return 0
|
|
return parseFloat(text)
|
|
}
|
|
|
|
const scrapePage = async (browser, url, isToday) => {
|
|
let result = {}
|
|
|
|
const page = await browser.newPage()
|
|
await page.goto(url)
|
|
|
|
const weatherTable = await page.locator('.weather_table').waitHandle()
|
|
|
|
const startTime = isToday ? new Date().getHours() + 1 : 1
|
|
const endTime = 24
|
|
|
|
if (isToday) {
|
|
try {
|
|
const row = await weatherTable.$$('.latest_detection')
|
|
const fields = await row[1]?.$$('td')
|
|
const temperature = await fields[2].evaluate(parseTemp)
|
|
const precipitation = await fields[3].evaluate(parsePrec)
|
|
result[startTime - 1] = {
|
|
temperature,
|
|
precipitation,
|
|
apparentTemperature: null,
|
|
weatherCode: null,
|
|
}
|
|
} catch (error) {
|
|
result[startTime - 1] = null
|
|
// console.log(error)
|
|
}
|
|
}
|
|
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`
|
|
|
|
const fields = await weatherTable.$$(selector)
|
|
|
|
const temperature = await fields[2].evaluate(parseTemp)
|
|
const precipitation = await fields[3].evaluate(parsePrec)
|
|
const apparentTemperature = await fields[6].evaluate(parseTemp)
|
|
result[i] = {
|
|
temperature,
|
|
precipitation,
|
|
apparentTemperature,
|
|
weatherCode: null,
|
|
}
|
|
} catch (error) {
|
|
result[i] = null
|
|
// console.log(error)
|
|
}
|
|
}
|
|
|
|
await page.close()
|
|
|
|
return result
|
|
}
|
|
|
|
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]
|
|
|
|
return results
|
|
}
|
|
|
|
const getDaySummary = day => {
|
|
let minimumTemperature = Number.MAX_VALUE
|
|
let maximumTemperature = Number.MIN_VALUE
|
|
let minimumApparentTemperature = Number.MAX_VALUE
|
|
let maximumApparentTemperature = Number.MIN_VALUE
|
|
let precipitationSum = 0
|
|
for (const h in day) {
|
|
minimumTemperature = Math.min(minimumTemperature, day[h]?.temperature)
|
|
maximumTemperature = Math.max(maximumTemperature, day[h]?.temperature)
|
|
minimumApparentTemperature = Math.min(
|
|
minimumApparentTemperature,
|
|
day[h]?.apparentTemperature,
|
|
)
|
|
maximumApparentTemperature = Math.max(
|
|
maximumApparentTemperature,
|
|
day[h]?.apparentTemperature,
|
|
)
|
|
precipitationSum += day[h]?.precipitation
|
|
}
|
|
return {
|
|
minimumTemperature,
|
|
maximumTemperature,
|
|
minimumApparentTemperature,
|
|
maximumApparentTemperature,
|
|
precipitationSum,
|
|
weatherCode: null,
|
|
}
|
|
}
|
|
|
|
export default async browser => {
|
|
const url = text => `https://www.ilmeteo.it/meteo/Pisa/${text}`
|
|
|
|
const results = rearrangeResults(
|
|
await Promise.all([
|
|
scrapePage(browser, url(''), true),
|
|
scrapePage(browser, url('domani'), false),
|
|
scrapePage(browser, url('dopodomani'), false),
|
|
scrapePage(browser, url('3'), false),
|
|
scrapePage(browser, url('4'), false),
|
|
scrapePage(browser, url('5'), false),
|
|
scrapePage(browser, url('6'), false),
|
|
]),
|
|
)
|
|
|
|
return {
|
|
today: results[0],
|
|
tomorrow: results[1],
|
|
dayAfterTomorrow: results[2],
|
|
week: { ...results.map(getDaySummary) },
|
|
}
|
|
}
|