Skip to content

Commit 964a386

Browse files
authored
fix(route/now): use api (#19208)
1 parent 5596129 commit 964a386

File tree

1 file changed

+93
-33
lines changed

1 file changed

+93
-33
lines changed

lib/routes/now/news.ts

Lines changed: 93 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,18 @@
11
import { Route } from '@/types';
22
import cache from '@/utils/cache';
3-
import got from '@/utils/got';
3+
import ofetch from '@/utils/ofetch';
44
import { load } from 'cheerio';
55
import { parseDate } from '@/utils/parse-date';
66

7+
const mainCategories = {
8+
local: 119,
9+
international: 120,
10+
entertainment: 500,
11+
life: 501,
12+
technology: 502,
13+
finance: 121,
14+
};
15+
716
const categories = {
817
tracker: 123,
918
feature: 124,
@@ -25,7 +34,8 @@ export const route: Route = {
2534
},
2635
radar: [
2736
{
28-
source: ['news.now.com/'],
37+
source: ['news.now.com/home/:category?', 'news.now.com/'],
38+
target: '/news/:category?',
2939
},
3040
],
3141
name: '新聞',
@@ -52,53 +62,103 @@ export const route: Route = {
5262
};
5363

5464
async function handler(ctx) {
55-
const category = ctx.req.param('category') || '';
56-
const id = ctx.req.param('id') || '';
65+
const { category = '', id = '' } = ctx.req.param();
66+
const limit = Number.parseInt(ctx.req.query('limit') || '20', 10);
67+
const hasTopicId = id && Object.hasOwn(categories, category);
5768

5869
const rootUrl = 'https://news.now.com';
5970

60-
const currentUrl = Object.hasOwn(categories, category) ? `${rootUrl}/home/${category}/detail?catCode=${categories[category]}&topicId=${id}` : `${rootUrl}/home${category ? `/${category}` : ''}`;
61-
62-
const response = await got({
63-
method: 'get',
64-
url: currentUrl,
65-
});
66-
67-
const $ = load(response.data);
68-
69-
const list = $(`${category === '' ? '.homeFeaturedNews ' : '.newsCategoryColLeft '}.newsTitle`)
70-
.toArray()
71-
.map((item) => {
72-
item = $(item);
73-
74-
return {
75-
title: item.text(),
76-
link: `${rootUrl}${item.parent().parent().attr('href')}`,
77-
};
78-
});
71+
const pageUrl = hasTopicId ? `${rootUrl}/home/${category}/detail?catCode=${categories[category]}&topicId=${id}` : `${rootUrl}/home${category ? `/${category}` : ''}`;
72+
73+
let apiUrl;
74+
if (hasTopicId) {
75+
apiUrl = pageUrl;
76+
} else if (category === 'sports') {
77+
apiUrl = `https://sportsapi.now.com/api/getNewsList?pageSize=${limit}&pageNo=1&searchTagsKey=allSportsSearchTags`;
78+
} else if (category) {
79+
apiUrl = `https://d3sli7vh0lsda4.cloudfront.net/api/getNewsList?category=${mainCategories[category]}&pageNo=1&pageSize=${limit}`;
80+
} else {
81+
apiUrl = pageUrl;
82+
}
83+
84+
const response = await ofetch(apiUrl);
85+
const isApi = typeof response === 'object' && Array.isArray(response);
86+
const $ = load(response);
87+
88+
let list;
89+
if (isApi) {
90+
list =
91+
category === 'sports'
92+
? response.map((item) => {
93+
const image = item.newsPhotos
94+
?.filter((p) => p.sizeType === '3')
95+
?.map((p) => `<img src="${p.imageFileUrl}">`)
96+
.join('');
97+
return {
98+
title: item.headlineChi,
99+
description: image,
100+
link: `https://news.now.com/home/${category}/player?newsId=${item.newsId}`,
101+
pubDate: parseDate(item.publishDate, 'x'),
102+
category: [...item.sportTypes.map((t) => t.sportTypeNameChi), ...item.players.map((p) => p.playerFullNameChi), ...item.teams.map((t) => t.teamCodeChi)],
103+
image: item.newsPhotos?.filter((p) => p.sizeType === '3')?.[0]?.imageUrl,
104+
newsId: item.newsId,
105+
};
106+
})
107+
: response.map((item) => {
108+
const image = item.image2Url ?? item.imageUrl ?? item.image3Url;
109+
return {
110+
title: item.title,
111+
description: (image ? `<img src="${image}">` : '') + item.leading + item.summary,
112+
link: `https://news.now.com/home/${category}/player?newsId=${item.newsId}`,
113+
pubDate: parseDate(item.publishDate, 'x'),
114+
updated: parseDate(item.lastModifyDate, 'x'),
115+
category: item.newsTags.map((t) => t.tag),
116+
image,
117+
};
118+
});
119+
} else {
120+
list = $(`${category === '' ? '.homeFeaturedNews ' : '.newsCategoryColLeft '}.newsTitle`)
121+
.toArray()
122+
.slice(0, limit)
123+
.map((item) => {
124+
item = $(item);
125+
126+
return {
127+
title: item.text(),
128+
link: `${rootUrl}${item.parent().parent().attr('href')}`,
129+
};
130+
});
131+
}
79132

80133
const items = await Promise.all(
81134
list.map((item) =>
82135
cache.tryGet(item.link, async () => {
83-
const detailResponse = await got({
84-
method: 'get',
85-
url: item.link,
86-
});
87-
const content = load(detailResponse.data);
136+
if (!item.pubDate || item.newsId) {
137+
const detailResponse = await ofetch(item.link);
138+
const $ = load(detailResponse);
139+
140+
const newsData = JSON.parse(
141+
$('script:contains("var newsData")')
142+
.text()
143+
.match(/var newsData = (.*?);/)?.[1] || '{}'
144+
);
88145

89-
const images = detailResponse.data.match(/"imageUrl":"(.*?)","image2Url":/);
146+
const images = newsData.imageList ? newsData.imageList.map((img) => `<img src="${img.image2Url}">`).join('') : '';
90147

91-
item.pubDate = parseDate(content('.published').attr('datetime'));
92-
item.description = (images ? `<img src="${images[1]}">` : '') + content('.newsLeading').html();
148+
item.description = item.description ? item.description + ($('.img_caption').prop('outerHTML') ?? '') + $('.newsLeading').html() : images + $('.newsLeading').html();
149+
item.pubDate ||= parseDate(newsData.publishDate, 'x');
150+
item.updated ||= parseDate(newsData.lastModifyDate, 'x');
151+
item.category ||= [...new Set([newsData.categoryName, ...newsData.newsTags.map((t) => t.tag), ...newsData.newsTopics.map((t) => t.topicName)])];
152+
}
93153

94154
return item;
95155
})
96156
)
97157
);
98158

99159
return {
100-
title: String(Object.hasOwn(categories, category) ? $('title').text() : ($('.smallSpace.active').text() || '首頁') + ' | Now 新聞'),
101-
link: currentUrl,
160+
title: Object.hasOwn(categories, category) ? $('title').text() : ($('.smallSpace.active').text() || '首頁') + ' | Now 新聞',
161+
link: pageUrl,
102162
item: items,
103163
};
104164
}

0 commit comments

Comments
 (0)