From 81d2230cd67a84521ebf601574bbb73e1eecb392 Mon Sep 17 00:00:00 2001 From: DIYgod Date: Thu, 15 Oct 2026 02:28:10 +0800 Subject: [PATCH] fix(route): retrieve HUBU mobile China News articles --- lib/routes/hubu/index.ts | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/lib/routes/hubu/index.ts b/lib/routes/hubu/index.ts index 49c826fc40..c8a74b4b7b 100644 --- a/lib/routes/hubu/index.ts +++ b/lib/routes/hubu/index.ts @@ -5,10 +5,38 @@ import pMap from 'p-map'; import type { DataItem, Language, Route } from '@/types'; import cache from '@/utils/cache'; import got from '@/utils/got'; +import ofetch from '@/utils/ofetch'; import { parseDate } from '@/utils/parse-date'; import { getRouteLimit } from '@/utils/route-limit'; import timezone from '@/utils/timezone'; +interface MobileChinanewsResponse { + msgcode: number; + data: { + title: string; + content: string; + keywords?: string[]; + }; +} + +const fetchMobileChinanewsArticle = async (articleId: string) => { + const response = await ofetch(`https://dw.chinanews.com/cns/app/v1/wapDetail/content/${articleId}.json`, { + query: { language: 'chs' }, + }); + if (response.msgcode !== 0 || !response.data?.title || !response.data.content) { + throw new Error(`China News did not return the content of article ${articleId}.`); + } + const $ = load(response.data.content, undefined, false); + $('.btpauthor, script, style').remove(); + const description = $.root().html(); + return { + title: response.data.title, + description, + category: response.data.keywords?.filter(Boolean), + content: { html: description, text: $.root().text() }, + }; +}; + export const handler = async (ctx) => { const { category = 'index/tzgg' } = ctx.req.param(); const limit = getRouteLimit(ctx, 20); @@ -49,11 +77,16 @@ export const handler = async (ctx) => { items = await pMap( items, async (item) => { - const detail = await cache.tryGet(`hubu:content:v2:${item.link}`, async () => { + const articleUrl = new URL(item.link); + const mobileChinanews = articleUrl.hostname === 'm.chinanews.com' && /^\/wap\/detail\/chs\/[^/]+\/(\d+)\.shtml$/.exec(articleUrl.pathname); + const detail = await cache.tryGet(`hubu:content:${mobileChinanews ? 'v3' : 'v2'}:${item.link}`, async () => { + if (mobileChinanews) { + return fetchMobileChinanewsArticle(mobileChinanews[1]); + } const { data: detailBuffer } = await got(item.link, { responseType: 'buffer' }); const charset = /charset=["']?([^"'\s>;]+)/i.exec(detailBuffer.toString('ascii'))?.[1] ?? 'utf-8'; const $$ = load(iconv.decode(detailBuffer, charset)); - const hubeiChinanews = new URL(item.link).hostname === 'www.hb.chinanews.com.cn'; + const hubeiChinanews = articleUrl.hostname === 'www.hb.chinanews.com.cn'; const title = $$('div.dtl-tit h4, div.con-tit h4').text() || (hubeiChinanews ? $$('.de_head .t1').text() : ''); if (!title) { return {};