fix(route): guokr channel path (#14969)

This commit is contained in:
Tony 2024-03-26 05:42:33 +08:00 committed by GitHub
parent 6e53d7263c
commit 25efba7596
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 68 additions and 67 deletions

View File

@ -1,15 +1,6 @@
import { Route } from '@/types';
import cache from '@/utils/cache';
import got from '@/utils/got';
async function loadFullPage(id) {
const link = `https://apis.guokr.com/minisite/article/${id}.json`;
const content = await cache.tryGet(link, async () => {
const res = await got(link);
return res.data.result.content;
});
return content;
}
import { parseList, parseItem } from './utils';
const channelMap = {
calendar: 'pac',
@ -19,21 +10,13 @@ const channelMap = {
};
export const route: Route = {
path: '/:channel',
path: '/column/:channel',
categories: ['new-media'],
example: '/guokr/calendar',
example: '/guokr/column/calendar',
parameters: { channel: '专栏类别' },
features: {
requireConfig: false,
requirePuppeteer: false,
antiCrawler: false,
supportBT: false,
supportPodcast: false,
supportScihub: false,
},
radar: [
{
source: ['guokr.com/'],
source: ['guokr.com/:channel'],
},
],
name: '果壳网专栏',
@ -48,29 +31,28 @@ export const route: Route = {
async function handler(ctx) {
const channel = channelMap[ctx.req.param('channel')] ?? ctx.req.param('channel');
const response = await got(`https://www.guokr.com/apis/minisite/article.json?retrieve_type=by_wx&channel_key=${channel}&offset=0&limit=10`);
const items = response.data.result;
const { data: response } = await got(`https://www.guokr.com/apis/minisite/article.json`, {
searchParams: {
retrieve_type: 'by_wx',
channel_key: channel,
offset: 0,
limit: 10,
},
});
const result = parseList(response.result);
if (items.length === 0) {
if (result.length === 0) {
throw new Error('Unknown channel');
}
const channel_name = items[0].channels[0].name;
const channel_url = items[0].channels[0].url;
const channelName = result[0].channels[0].name;
const channelUrl = result[0].channels[0].url;
const result = await Promise.all(
items.map(async (item) => ({
title: item.title,
description: await loadFullPage(item.id), // Mercury 无法正确解析全文,故这里手动加载
pubDate: item.date_published,
link: item.url,
author: item.author.nickname,
}))
);
const items = await Promise.all(result.map((item) => parseItem(item)));
return {
title: `果壳网 ${channel_name}`,
link: channel_url,
item: result,
title: `果壳网 ${channelName}`,
link: channelUrl,
item: items,
};
}

View File

@ -1,21 +1,11 @@
import { Route } from '@/types';
import cache from '@/utils/cache';
import got from '@/utils/got';
import { load } from 'cheerio';
import { parseList, parseItem } from './utils';
export const route: Route = {
path: '/scientific',
categories: ['new-media'],
example: '/guokr/scientific',
parameters: {},
features: {
requireConfig: false,
requirePuppeteer: false,
antiCrawler: false,
supportBT: false,
supportPodcast: false,
supportScihub: false,
},
radar: [
{
source: ['guokr.com/scientific', 'guokr.com/'],
@ -28,29 +18,21 @@ export const route: Route = {
};
async function handler() {
const response = await got('https://www.guokr.com/apis/minisite/article.json?retrieve_type=by_subject&limit=20&offset=0');
const { data: response } = await got('https://www.guokr.com/beta/proxy/science_api/articles', {
searchParams: {
retrieve_type: 'by_category',
page: 1,
},
});
const result = response.data.result;
const result = parseList(response);
const items = await Promise.all(result.map((item) => parseItem(item)));
return {
title: '果壳网 科学人',
link: 'https://www.guokr.com/scientific',
description: '果壳网 科学人',
item: await Promise.all(
result.map((item) =>
cache.tryGet(item.url, async () => {
const res = await got(item.url);
const $ = load(res.data);
item.description = $('.eflYNZ #js_content').css('visibility', 'visible').html() ?? $('.bxHoEL').html();
return {
title: item.title,
description: item.description,
pubDate: item.date_published,
link: item.url,
author: item.author.nickname,
};
})
)
),
item: items,
};
}

37
lib/routes/guokr/utils.ts Normal file
View File

@ -0,0 +1,37 @@
import { parseDate } from '@/utils/parse-date';
import cache from '@/utils/cache';
import got from '@/utils/got';
import * as cheerio from 'cheerio';
export const parseList = (result) =>
result.map((item) => ({
title: item.title,
description: item.summary,
pubDate: parseDate(item.date_published),
link: `https://www.guokr.com/article/${item.id}/`,
author: item.author.nickname,
category: item.subject?.name,
id: item.id,
channels: item.channels,
}));
export const parseItem = (item) =>
cache.tryGet(item.link, async () => {
const { data: res } = await got(`https://apis.guokr.com/minisite/article/${item.id}.json`);
const $ = cheerio.load(res.result.content);
$('#meta_content').remove();
$('div').each((_, elem) => {
const $elem = $(elem);
$elem.attr('style', $elem.attr('style')?.replaceAll(/display:none;|visibility: hidden;/g, ''));
});
$('img').each((_, elem) => {
const $elem = $(elem);
if ($elem.attr('data-src')) {
$elem.attr('src', $elem.attr('data-src'));
}
});
item.description = $.html();
return item;
});