feat(route): qstheory magazine (#17591)

This commit is contained in:
Tony
2024-11-15 19:52:40 +08:00
committed by GitHub
parent e8f020e31c
commit 47ae077dee
6 changed files with 217 additions and 125 deletions
-3
View File
@@ -1455,9 +1455,6 @@ router.get('/deepl/blog/:lang?', lazyloadRouteHandler('./routes/deepl/blog'));
router.get('/muchong/journal/:type?', lazyloadRouteHandler('./routes/muchong/journal'));
router.get('/muchong/:id/:type?/:sort?', lazyloadRouteHandler('./routes/muchong/index'));
// 求是网
router.get('/qstheory/:category?', lazyloadRouteHandler('./routes/qstheory/index'));
// 生命时报
router.get('/lifetimes/:category?', lazyloadRouteHandler('./routes/lifetimes/index'));
-122
View File
@@ -1,122 +0,0 @@
const got = require('@/utils/got');
const cheerio = require('cheerio');
const rootUrl = 'http://www.qstheory.cn/';
const config = {
toutiao: {
title: '头条',
url: `${rootUrl}/v9zhuanqu/toutiao/index.htm`,
},
qswp: {
title: '网评',
url: `${rootUrl}/qswp.htm`,
},
qssp: {
title: '视频',
url: `${rootUrl}/qssp/index.htm`,
},
qslgxd: {
title: '原创',
url: `${rootUrl}/qslgxd/index.htm`,
},
economy: {
title: '经济',
url: `${rootUrl}/economy/index.htm`,
},
politics: {
title: '政治',
url: `${rootUrl}/politics/index.htm`,
},
culture: {
title: '文化',
url: `${rootUrl}/culture/index.htm`,
},
society: {
title: '社会',
url: `${rootUrl}/society/index.htm`,
},
cpc: {
title: '党建',
url: `${rootUrl}/cpc/index.htm`,
},
science: {
title: '科教',
url: `${rootUrl}/science/index.htm`,
},
zoology: {
title: '生态',
url: `${rootUrl}/zoology/index.htm`,
},
defense: {
title: '国防',
url: `${rootUrl}/defense/index.htm`,
},
international: {
title: '国际',
url: `${rootUrl}/international/index.htm`,
},
books: {
title: '图书',
url: `${rootUrl}/books/index.htm`,
},
xxbj: {
title: '学习笔记',
url: `${rootUrl}/qszq/xxbj/index.htm`,
},
};
module.exports = async (ctx) => {
const category = ctx.params.category || 'toutiao';
const currentUrl = config[category].url;
const response = await got({
method: 'get',
url: currentUrl,
});
const $ = cheerio.load(response.data);
const list = $('.list-style1 ul li a, .text h2 a, .no-pic ul li a')
.slice(0, 15)
.map((_, item) => {
item = $(item);
return {
title: item.text(),
link: item.attr('href'),
};
})
.get();
const items = await Promise.all(
list.map((item) =>
ctx.cache.tryGet(item.link, async () => {
const detailResponse = await got({
method: 'get',
url: item.link,
});
const content = cheerio.load(detailResponse.data);
content('.fs-text, .fs-pinglun, .hidden-xs').remove();
item.author = content('.appellation').text();
item.description = content('.highlight, .text').html() || content('.content').html();
item.pubDate = new Date(
content('.puttime_mobi, .pubtime, .headtitle span')
.text()
.replace('发表于', '')
.replaceAll(/(年|月)/g, '-')
.replace('日', '')
).toUTCString();
return item;
})
)
);
ctx.state.data = {
title: $('title').text(),
link: currentUrl,
item: items,
};
};
+121
View File
@@ -0,0 +1,121 @@
import { Route } from '@/types';
import ofetch from '@/utils/ofetch';
import * as cheerio from 'cheerio';
import cache from '@/utils/cache';
import { baseUrl as rootUrl, getItem } from './utils';
const config = {
toutiao: {
title: '头条',
url: `${rootUrl}/v9zhuanqu/toutiao/index.htm`,
},
qswp: {
title: '网评',
url: `${rootUrl}/qswp.htm`,
},
qssp: {
title: '视频',
url: `${rootUrl}/qssp/index.htm`,
},
qslgxd: {
title: '原创',
url: `${rootUrl}/qslgxd/index.htm`,
},
economy: {
title: '经济',
url: `${rootUrl}/economy/index.htm`,
},
politics: {
title: '政治',
url: `${rootUrl}/politics/index.htm`,
},
culture: {
title: '文化',
url: `${rootUrl}/culture/index.htm`,
},
society: {
title: '社会',
url: `${rootUrl}/society/index.htm`,
},
cpc: {
title: '党建',
url: `${rootUrl}/cpc/index.htm`,
},
science: {
title: '科教',
url: `${rootUrl}/science/index.htm`,
},
zoology: {
title: '生态',
url: `${rootUrl}/zoology/index.htm`,
},
defense: {
title: '国防',
url: `${rootUrl}/defense/index.htm`,
},
international: {
title: '国际',
url: `${rootUrl}/international/index.htm`,
},
books: {
title: '图书',
url: `${rootUrl}/books/index.htm`,
},
xxbj: {
title: '学习笔记',
url: `${rootUrl}/qszq/xxbj/index.htm`,
},
llwx: {
title: '理论文选',
url: `${rootUrl}/qszq/llwx/index.htm`,
},
};
export const route: Route = {
path: '/:category?',
categories: ['traditional-media'],
example: '/qstheory',
parameters: { industry: '分类,见下表' },
radar: [
{
source: ['www.qstheory.cn/v9zhuanqu/:category/index.htm', 'www.qstheory.cn/qszq/:category/index.htm', 'www.qstheory.cn/:category/index.htm'],
},
],
name: '分类',
maintainers: ['nczitzk'],
handler,
description: `
| 头条 | 网评 | 视频 | 原创 | 经济 | 政治 | 文化 | 社会 | 党建 | 科教 | 生态 | 国防 | 国际 | 图书 | 学习笔记 | 理论文选 |
| ------- | ---- | ---- | ------ | ------- | -------- | ------- | ------- | ---- | ------- | ------- | ------- | ------------- | ----- | -------- | -------- |
| toutiao | qswp | qssp | qslgxd | economy | politics | culture | society | cpc | science | zoology | defense | international | books | xxbj | llwx |`,
};
async function handler(ctx) {
const { category = 'toutiao' } = ctx.req.param();
const limit = Number.parseInt(ctx.req.query('limit')) || 50;
const currentUrl = config[category].url;
const response = await ofetch(currentUrl);
const $ = cheerio.load(response);
const list = $('.list-style1 ul li a, .text h2 a, .no-pic ul li a')
.slice(0, limit)
.toArray()
.map((item) => {
const $item = $(item);
return {
title: $item.text(),
link: $item.attr('href')!,
};
});
const items = await Promise.all(list.map((item) => cache.tryGet(item.link, () => getItem(item))));
return {
title: $('title').text(),
link: currentUrl,
item: items,
};
}
+64
View File
@@ -0,0 +1,64 @@
import { Route } from '@/types';
import ofetch from '@/utils/ofetch';
import * as cheerio from 'cheerio';
import cache from '@/utils/cache';
import { baseUrl, getItem } from './utils';
export const route: Route = {
path: '/magazine/:magazine',
categories: ['traditional-media'],
example: '/qstheory/magazine/qs',
parameters: { magazine: '刊物,`qs` 为求是,`hqwglist` 为红旗文稿' },
radar: [
{
source: ['www.qstheory.cn/:magazine/mulu.htm'],
},
],
name: '在线读刊',
maintainers: ['TonyRL'],
handler,
};
async function handler(ctx) {
const { magazine } = ctx.req.param();
const link = `${baseUrl}/${magazine}/mulu.htm`;
const yearResponse = await ofetch(link);
const $ = cheerio.load(yearResponse);
const yearList = $('.booktitle a')
.toArray()
.map((item) => {
const $item = $(item);
return {
title: $item.text(),
link: $item.attr('href')!,
};
});
const issueResponse = await ofetch(yearList[0].link);
const $$ = cheerio.load(issueResponse);
const list = $$('.highlight span a')
.toArray()
.map((item) => {
const $item = $$(item);
return {
title: $item.text(),
link: $item.attr('href')!,
};
})
.toReversed()
.filter((item) => item.title);
const items = await Promise.all(list.map((item) => cache.tryGet(item.link, () => getItem(item))));
return {
title: $('head title').text(),
link,
image: new URL($('.book img').attr('src')!, link).href,
item: items,
};
}
+7
View File
@@ -0,0 +1,7 @@
import type { Namespace } from '@/types';
export const namespace: Namespace = {
name: '求是网',
url: 'www.qstheory.cn',
lang: 'zh-CN',
};
+25
View File
@@ -0,0 +1,25 @@
import ofetch from '@/utils/ofetch';
import * as cheerio from 'cheerio';
import { parseDate } from '@/utils/parse-date';
export const baseUrl = 'http://www.qstheory.cn';
export const getItem = async (item) => {
const response = await ofetch(item.link);
const $ = cheerio.load(response);
$('.fs-text, .fs-pinglun, .hidden-xs').remove();
item.author = $('.appellation').text();
item.description = $('.highlight, .text').html() || $('.content').html();
item.pubDate = parseDate(
$('.puttime_mobi, .pubtime, .headtitle span')
.text()
.trim()
.replace('发表于', '')
.replaceAll(/(年|月)/g, '-')
.replace('日', '')
);
return item;
};