const FORMAT = { hourly: { temperature: { type: 'number', unit: '°C', }, precipitationProbability: { type: 'number', unit: '%', }, // weatherCode: { // type: 'number', // unit: 'Aeronautica Militare Weather Icons', // }, }, daily: { minimumTemperature: { type: 'number', unit: '°C', }, maximumTemperature: { type: 'number', unit: '°C', }, // weatherCode: { // type: 'number', // unit: 'Aeronautica Militare Weather Icons', // }, }, } const range = (start, end) => { /// returns [start .. (end-1)] return [...Array(end - start).keys()].map(x => x + start) } const parseTemp = el => { // return el.textContent return parseFloat(el.textContent) } const parsePrecProb = el => { const text = el.textContent.trim() return parseFloat(text) return text if (text === 'assenti') return 0 if (text === 'deboli') return 0.05 try { //TODO not 100% sure that this would work as it was never tested } catch (error) { console.log(error) return text } } export default async browser => { const page = await browser.newPage() await page.goto('https://www.meteoam.it/it/meteo-citta/pisa') const meteogramInfoContainer = await page .locator('.meteogram-info-container') .waitHandle() const startTime = new Date().getHours() + 1 const endTime = 24 const scrapeColumn = async i => { const column = await meteogramInfoContainer.$( `#weather_info_container_${i}`, ) const tempDiv = await column.$('.weather-info-temperature') const precProbDiv = await column.$('.weather-rain-probability') const temperature = await tempDiv.evaluate(parseTemp) const precipitationProbability = await precProbDiv.evaluate(parsePrecProb) return { temperature, precipitationProbability } } const scrapeBlock = async i => { const block = await meteogramInfoContainer.$( `.swiper-slide[aria-label="${i + 1} / 5"]`, ) const tempMaxDiv = await block.$('.meteogram-info-temp-max') const tempMinDiv = await block.$('.meteogram-info-temp-min') const maximumTemperature = await tempMaxDiv.evaluate(parseTemp) const minimumTemperature = await tempMinDiv.evaluate(parseTemp) return { minimumTemperature, maximumTemperature } } const scrapeToday = async () => { let today = {} const indices = range(startTime, endTime) const results = await Promise.all(indices.map(scrapeColumn)) for (let i = startTime; i < endTime; i++) { today[i] = results[i - startTime] } return today } const scrapeTomorrow = async () => { let tomorrow = {} const indices = range(24 - startTime, 48 - startTime) const results = await Promise.all(indices.map(scrapeColumn)) for (let i = 0; i < 24; i++) { tomorrow[i] = results[i] } return tomorrow } const scrapeDayAfterTomorrow = async () => { let dayAfterTomorrow = {} const indices = range(48 - startTime, 72 - startTime) const results = await Promise.all(indices.map(scrapeColumn)) for (let i = 0; i < 24; i++) { dayAfterTomorrow[i] = results[i] } return dayAfterTomorrow } const scrapeWeek = async () => { let week = {} const indices = range(0, 5) const results = await Promise.all(indices.map(scrapeBlock)) for (let i = 0; i < 5; i++) { week[i] = results[i] } return week } const [today, tomorrow, dayAfterTomorrow, week] = await Promise.all([ scrapeToday(), scrapeTomorrow(), scrapeDayAfterTomorrow(), scrapeWeek(), ]) await page.close() return { format: FORMAT, today, tomorrow, dayAfterTomorrow, week, } }