feat(route/meteoblue): add namespace and weather news route (#19770)

This commit is contained in:
tssujt 2025-08-08 19:26:09 +08:00 committed by GitHub
parent 616aa24dee
commit a6cae9afbb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 83 additions and 0 deletions

View File

@ -0,0 +1,8 @@
import type { Namespace } from '@/types';
export const namespace: Namespace = {
name: 'meteoblue',
url: 'meteoblue.com',
lang: 'en',
description: 'Weather forecasts, climate data, and meteorological news from meteoblue',
};

View File

@ -0,0 +1,75 @@
import { Route } from '@/types';
import { load } from 'cheerio';
import ofetch from '@/utils/ofetch';
import { parseDate } from '@/utils/parse-date';
export const route: Route = {
path: '/weathernews',
name: 'Weather News',
maintainers: ['tssujt'],
handler,
example: '/meteoblue/weathernews',
categories: ['blog'],
features: {
requireConfig: false,
requirePuppeteer: false,
antiCrawler: false,
supportBT: false,
supportPodcast: false,
supportScihub: false,
},
description: 'Weather news and articles from meteoblue',
};
async function handler() {
const baseUrl = 'https://www.meteoblue.com';
const url = `${baseUrl}/en/blog/article/weathernews`;
const response = await ofetch(url);
const $ = load(response);
// Extract articles from the page using the actual HTML structure
const articles = $('article[itemprop="blogPost"]')
.toArray()
.map((element) => {
const $article = $(element);
// Get title and link from h3 > a
const $link = $article.find('h3[itemprop="headline"] a[itemprop="mainEntityOfPage"]');
const title = $link.text().trim();
const link = $link.attr('href');
if (!title || !link) {
return null;
}
// Get date from time element
const $time = $article.find('time[itemprop="datePublished"]');
const dateText = $time.attr('datetime') || '';
// Extract author from the time element text
const $authorMeta = $article.find('meta[itemprop="author"]');
const author = $authorMeta.attr('content')?.trim() || 'meteoblue';
// Get description from itemprop="description"
const $description = $article.find('div[itemprop="description"]');
const description = $description.text().trim() || title;
return {
title,
link: link.startsWith('http') ? link : `${baseUrl}${link}`,
pubDate: dateText ? parseDate(dateText) : undefined,
author,
description,
};
})
.filter(Boolean);
return {
title: 'meteoblue Weather News',
link: url,
description: 'Latest weather news and articles from meteoblue',
item: articles,
allowEmpty: true,
};
}