feat(route): add 木木博客频道 & 标签 & 专题 & 搜索 (#13170)
* feature(route): add 木木博客频道 & 标签 & 专题 & 搜索 * fix typo
This commit is contained in:
parent
73bb1083cd
commit
c103270f7f
|
|
@ -0,0 +1,98 @@
|
|||
const got = require('@/utils/got');
|
||||
const cheerio = require('cheerio');
|
||||
const { parseDate } = require('@/utils/parse-date');
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const { params } = ctx.params;
|
||||
const limit = ctx.query.limit ? parseInt(ctx.query.limit, 10) : 20;
|
||||
|
||||
const rootUrl = 'https://www.liulinblog.com';
|
||||
const currentUrl = params ? new URL(params, rootUrl).href : rootUrl;
|
||||
|
||||
const { data: response } = await got(currentUrl);
|
||||
|
||||
const $ = cheerio.load(response);
|
||||
|
||||
let items = $('div.scroll')
|
||||
.first()
|
||||
.find('article')
|
||||
.slice(0, limit)
|
||||
.toArray()
|
||||
.map((item) => {
|
||||
item = $(item);
|
||||
|
||||
const a = item.find('h2.entry-title a');
|
||||
|
||||
return {
|
||||
title: a.prop('title'),
|
||||
link: a.prop('href'),
|
||||
description: item.find('div.entry-excerpt').html(),
|
||||
author: item
|
||||
.find('span.meta-author a')
|
||||
.toArray()
|
||||
.map((a) => $(a).prop('title'))
|
||||
.join(' / '),
|
||||
category: item
|
||||
.find('span.meta-category-dot a[rel="category"]')
|
||||
.toArray()
|
||||
.map((c) => $(c).text()),
|
||||
guid: `liulinblog-${item.prop('id')}`,
|
||||
pubDate: parseDate(item.find('span.meta-date time').prop('datetime')),
|
||||
comments: item.find('span.meta-comment').text() ? parseInt(item.find('span.meta-comment').text().trim(), 10) : 0,
|
||||
};
|
||||
});
|
||||
|
||||
items = await Promise.all(
|
||||
items.map((item) =>
|
||||
ctx.cache.tryGet(item.link, async () => {
|
||||
const { data: detailResponse } = await got(item.link);
|
||||
|
||||
const content = cheerio.load(detailResponse);
|
||||
|
||||
content('div[role="alert"]').remove();
|
||||
|
||||
item.title = content('meta[property="og:title"]').prop('content');
|
||||
item.description = content('div.entry-content').html();
|
||||
item.author = content('div.entry-meta')
|
||||
.first()
|
||||
.find('span.meta-author a')
|
||||
.toArray()
|
||||
.map((a) => content(a).prop('title'))
|
||||
.join(' / ');
|
||||
item.category = content('div.entry-meta')
|
||||
.first()
|
||||
.find('span.meta-category a[rel="category"]')
|
||||
.toArray()
|
||||
.map((c) => content(c).text());
|
||||
item.guid = `liulinblog-${content('article').first().prop('id')}`;
|
||||
item.pubDate = parseDate(content('span.meta-date time').first().prop('datetime'));
|
||||
item.comments = content('h3.comments-title').text()
|
||||
? parseInt(
|
||||
content('h3.comments-title')
|
||||
.text()
|
||||
.match(/\((\d+)\)/),
|
||||
10
|
||||
)
|
||||
: 0;
|
||||
|
||||
return item;
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
const icon = $('link[rel="icon"]').prop('href');
|
||||
const title = $('img.logo').prop('alt');
|
||||
|
||||
ctx.state.data = {
|
||||
item: items,
|
||||
title: `${title} - ${params ? $('h1.term-title').text().split('搜索到')[0] : '最新'}`,
|
||||
link: currentUrl,
|
||||
description: $('meta[name="description"]').prop('content'),
|
||||
language: 'zh-cn',
|
||||
image: $('img.logo').prop('src'),
|
||||
icon,
|
||||
logo: icon,
|
||||
subtitle: $('p.term-description').text(),
|
||||
author: title,
|
||||
};
|
||||
};
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
const got = require('@/utils/got');
|
||||
const { processList, processItems } = require('./utils');
|
||||
|
||||
const host = 'https://www.liulinblog.com';
|
||||
|
||||
const titleMap = {
|
||||
internet: '互联网早报',
|
||||
seo: '站长圈',
|
||||
};
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const channel = ctx.params.channel ?? 'internet';
|
||||
const url = `${host}/itnews/${channel}`;
|
||||
const response = await got(url);
|
||||
const list = processList(response);
|
||||
const items = await processItems(list, ctx);
|
||||
|
||||
ctx.state.data = {
|
||||
title: titleMap[channel],
|
||||
link: url,
|
||||
item: items,
|
||||
};
|
||||
};
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
const got = require('@/utils/got');
|
||||
const { processList, processItems } = require('./utils');
|
||||
|
||||
const host = 'https://www.liulinblog.com';
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const url = `${host}/kuaixun`;
|
||||
const response = await got(url);
|
||||
const list = processList(response);
|
||||
const items = await processItems(list, ctx);
|
||||
|
||||
ctx.state.data = {
|
||||
title: '每天六十秒(60秒)读懂世界',
|
||||
link: url,
|
||||
item: items,
|
||||
};
|
||||
};
|
||||
|
|
@ -1,4 +1,8 @@
|
|||
module.exports = {
|
||||
'/kuaixun': ['Fatpandac'],
|
||||
'/itnews/:channel?': ['Fatpandac'],
|
||||
'/itnews/:channel?': ['Fatpandac', 'nczitzk'],
|
||||
'/kuaixun': ['Fatpandac', 'nczitzk'],
|
||||
'/search/:keyword': ['nczitzk'],
|
||||
'/series/:id': ['nczitzk'],
|
||||
'/tag/:id': ['nczitzk'],
|
||||
'/:channel?': ['nczitzk'],
|
||||
};
|
||||
|
|
|
|||
|
|
@ -3,29 +3,49 @@ module.exports = {
|
|||
_name: '木木博客',
|
||||
'.': [
|
||||
{
|
||||
title: '每天六十秒(60秒)读懂世界',
|
||||
docs: 'https://docs.rsshub.app/routes/new-media#mu-mu-bo-ke',
|
||||
source: ['/kuaixun'],
|
||||
target: '/liulinblog/kuaixun',
|
||||
},
|
||||
{
|
||||
title: '互联网早报',
|
||||
docs: 'https://docs.rsshub.app/routes/new-media#mu-mu-bo-ke',
|
||||
source: ['/itnews/:channel'],
|
||||
target: (params) => {
|
||||
if (params.channel === 'internet') {
|
||||
return '/liulinblog/itnews/:channel';
|
||||
}
|
||||
title: '频道',
|
||||
docs: 'https://docs.rsshub.app/new-media.html#mu-mu-bo-ke',
|
||||
source: ['/:channel', '/'],
|
||||
target: (params, url) => {
|
||||
url = new URL(url);
|
||||
const path = url.href.match(/\.com(.*?)/)[1];
|
||||
|
||||
return `/liulinblog${path === '/' ? '' : path}`;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '站长圈',
|
||||
docs: 'https://docs.rsshub.app/routes/new-media#mu-mu-bo-ke',
|
||||
source: ['/itnews/:channel'],
|
||||
target: (params) => {
|
||||
if (params.channel === 'seo') {
|
||||
return '/liulinblog/itnews/:channel';
|
||||
}
|
||||
title: '标签',
|
||||
docs: 'https://docs.rsshub.app/new-media.html#mu-mu-bo-ke',
|
||||
source: ['/tag/:id', '/'],
|
||||
target: '/liulinblog/tag/:id',
|
||||
},
|
||||
{
|
||||
title: '专题',
|
||||
docs: 'https://docs.rsshub.app/new-media.html#mu-mu-bo-ke',
|
||||
source: ['/series/:id', '/'],
|
||||
target: '/liulinblog/series/:id',
|
||||
},
|
||||
{
|
||||
title: '搜索',
|
||||
docs: 'https://docs.rsshub.app/new-media.html#mu-mu-bo-ke',
|
||||
source: ['/search/:keyword', '/'],
|
||||
target: '/liulinblog/search/:keyword',
|
||||
},
|
||||
{
|
||||
title: '60秒读懂世界',
|
||||
docs: 'https://docs.rsshub.app/new-media.html#mu-mu-bo-ke',
|
||||
source: ['/kuaixun', '/'],
|
||||
target: '/liulinblog/kuaixun',
|
||||
},
|
||||
{
|
||||
title: '网络营销',
|
||||
docs: 'https://docs.rsshub.app/new-media.html#mu-mu-bo-ke',
|
||||
source: ['/:channel', '/'],
|
||||
target: (params, url) => {
|
||||
url = new URL(url);
|
||||
const path = url.href.match(/\.com(.*?)/)[1];
|
||||
|
||||
return `/liulinblog${path === '/' ? '' : path}`;
|
||||
},
|
||||
},
|
||||
],
|
||||
|
|
|
|||
|
|
@ -1,4 +1,8 @@
|
|||
module.exports = function (router) {
|
||||
router.get('/kuaixun', require('./kuaixun'));
|
||||
router.get('/itnews/:channel?', require('./itnews'));
|
||||
module.exports = (router) => {
|
||||
router.get('/itnews/:channel', (ctx) => {
|
||||
const { channel } = ctx.params;
|
||||
const redirectTo = `/liulinblog/${channel}`;
|
||||
ctx.redirect(redirectTo);
|
||||
});
|
||||
router.get('/:params*', require('./'));
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,42 +0,0 @@
|
|||
const got = require('@/utils/got');
|
||||
const cheerio = require('cheerio');
|
||||
const { parseDate } = require('@/utils/parse-date');
|
||||
|
||||
const processList = (res) => {
|
||||
const $ = cheerio.load(res.data);
|
||||
const list = $('div.archive.container > div.row > div > div > div.row.posts-wrapper.scroll > div')
|
||||
.map((_, item) => ({
|
||||
title: $(item).find('h2.entry-title').text(),
|
||||
link: $(item).find('h2.entry-title > a').attr('href'),
|
||||
pubDate: parseDate($(item).find('time').attr('datetime')),
|
||||
author: '60秒读懂世界',
|
||||
}))
|
||||
.get();
|
||||
|
||||
return list;
|
||||
};
|
||||
|
||||
const processItems = async (list, ctx) => {
|
||||
const items = await Promise.all(
|
||||
list.map((item) =>
|
||||
ctx.cache.tryGet(item.link, async () => {
|
||||
const detailResponse = await got(item.link);
|
||||
const $ = cheerio.load(detailResponse.data);
|
||||
const fullContent = $('div > div.entry-wrapper > div.entry-content');
|
||||
fullContent.find('img').remove();
|
||||
fullContent.find('div.pt-0').remove();
|
||||
fullContent.find('div.post-note').remove();
|
||||
item.description = fullContent.html();
|
||||
|
||||
return item;
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
return items;
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
processList,
|
||||
processItems,
|
||||
};
|
||||
|
|
@ -3719,17 +3719,91 @@ column 为 third 时可选的 category:
|
|||
|
||||
## 木木博客 {#mu-mu-bo-ke}
|
||||
|
||||
### 每天六十秒(60 秒)读懂世界 {#mu-mu-bo-ke-mei-tian-liu-shi-miao-%EF%BC%8860-miao-%EF%BC%89-du-dong-shi-jie}
|
||||
### 频道 {#mu-mu-bo-ke-pin-dao}
|
||||
|
||||
<Route author="Fatpandac" example="/liulinblog/kuaixun" path="/liulinblog/kuaixun"/>
|
||||
<Route author="nczitzk" example="/liulinblog" path="/liulinblog/:channel?" paramsDesc={['频道 id,可在对应频道页 URL 中找到,见下表,默认为最新']} radar="1" rssbud="1">
|
||||
|
||||
### 科技新闻 {#mu-mu-bo-ke-ke-ji-xin-wen}
|
||||
| 最新 | 60秒读懂世界 | 精品资源 | 视频资源 | 音频资源 |
|
||||
| ---- | ------------ | -------- | -------- | -------- |
|
||||
| | kuaixun | ziyuan | video | yinpin |
|
||||
|
||||
<Route author="Fatpandac" example="/liulinblog/itnews/seo" path="/liulinblog/itnews/:channel?" paramsDesc={['频道,默认为互联网早报']}>
|
||||
| 绝版资源 | 实用文档 | PPT素材 | 后期素材 | 技能教程 |
|
||||
| -------- | -------- | --------- | -------- | --------- |
|
||||
| jueban | wendang | ppt-sucai | sucai | jiaocheng |
|
||||
|
||||
| 互联网早报 | 站长圈 |
|
||||
| :--------: | :----: |
|
||||
| internet | seo |
|
||||
| 创业副业 | 单机游戏 | 冒险解谜 | 竞技格斗 | 赛车竞技 |
|
||||
| -------- | -------- | -------- | ----------- | -------- |
|
||||
| money | game | mxjm | jingjigedou | saiche |
|
||||
|
||||
| 模拟经营 | 角色扮演 | 飞行游戏 | 塔防策略 | 射击游戏 |
|
||||
| -------- | -------- | -------- | -------- | -------- |
|
||||
| moni | jiaose | feixing | tafang | sheji |
|
||||
|
||||
| 恐怖冒险 | 策略生存 | 动作冒险 | 电商运营 | 互联网早报 |
|
||||
| -------- | -------- | -------- | --------- | ---------- |
|
||||
| kongbu | celve | dongzuo | dianshang | internet |
|
||||
|
||||
| 站长圈 | 自媒体运营 | 短视频 |
|
||||
| ------ | ---------- | ----------- |
|
||||
| seo | zimeiti | duan-shipin |
|
||||
|
||||
</Route>
|
||||
|
||||
### 标签 {#mu-mu-bo-ke-biao-qian}
|
||||
|
||||
<Route author="nczitzk" example="/liulinblog/tag/qukuailian" path="/liulinblog/tag/:id" paramsDesc={['标签 id,可在对应标签页 URL 中找到,见下表']} radar="1" rssbud="1">
|
||||
|
||||
| 区块链 | 小红书 | 小说项目 | 微信公众号 | 微信营销 |
|
||||
| ---------- | ----------- | -------- | ---------- | -------- |
|
||||
| qukuailian | xiaohongshu | xiaoshuo | 微信公众号 | we-chat |
|
||||
|
||||
| 抖音 | 抖音直播 | 拼多多 | 支付宝 | 教育 |
|
||||
| ---- | -------- | --------- | ------ | ---- |
|
||||
| 抖音 | 抖音直播 | pinduoduo | alipay | 教育 |
|
||||
|
||||
| chrome插件 | galgame汉化游戏 | honeyselect 汉化游戏 | PSD笔刷素材 | ps插件 |
|
||||
| ---------- | --------------- | -------------------- | ----------- | ---------- |
|
||||
| chrome插件 | galgame | honey-select | psd-bishua | ps-chajian |
|
||||
|
||||
| vip视频 | windows实用技巧 | 下载软件 | 丝袜玉足 | 免费字体下载 |
|
||||
| ---------- | --------------- | -------- | -------- | ------------ |
|
||||
| vip-shipin | computer | download | siwa | ziti |
|
||||
|
||||
| 二战游戏下载 | 冒险解谜游戏 | 动作游戏下载 | 安卓游戏 | 策略游戏 |
|
||||
| ------------ | ------------ | ------------ | ------------ | ---------- |
|
||||
| war-games | 冒险解谜游戏 | 动作游戏下载 | android-game | game-celve |
|
||||
|
||||
| Pr插件 | Python | seo优化 | VLOG | wordpress | word技巧 |
|
||||
| ------ | ------ | ------- | ---- | --------- | -------- |
|
||||
| pr插件 | python | seo | vlog | wordpress | word |
|
||||
|
||||
</Route>
|
||||
|
||||
### 专题 {#mu-mu-bo-ke-zhuan-ti}
|
||||
|
||||
<Route author="nczitzk" example="/liulinblog/series/xunlei" path="/liulinblog/series/:id" paramsDesc={['专题 id,可在对应标签页 URL 中找到,见下表']} radar="1" rssbud="1">
|
||||
|
||||
| 【免费速存】迅雷资源合集 | 直播带货教程 | 电商培训课程 | 拼多多运营培训 | 小红书运营 | 抖音运营 | 闲鱼运营 | 短视频运营 |
|
||||
| ------------------------ | ------------ | --------------- | -------------- | ----------- | ------------- | ------------- | ----------------- |
|
||||
| xunlei | zhibodaihuo | dianshangpeixun | pinduoduo | xiaohongshu | douyinyunying | xianyuyunying | duanshipinyunying |
|
||||
|
||||
</Route>
|
||||
|
||||
### 搜索 {#mu-mu-bo-ke-sou-suo}
|
||||
|
||||
<Route author="nczitzk" example="/liulinblog/search/单机游戏" path="/liulinblog/search/:keyword" paramsDesc={['关键字']} radar="1" rssbud="1"/>
|
||||
|
||||
### 60秒读懂世界 {#mu-mu-bo-ke-60-miao-du-dong-shi-jie}
|
||||
|
||||
<Route author="Fatpandac nczitzk" example="/liulinblog/kuaixun" path="/liulinblog/kuaixun"/>
|
||||
|
||||
### 网络营销 {#mu-mu-bo-ke-wang-luo-ying-xiao}
|
||||
|
||||
<Route author="Fatpandac nczitzk" example="/liulinblog/itnews" path="/liulinblog/itnews/:channel?" paramsDesc={['频道,默认为网络营销']}>
|
||||
|
||||
| 网络营销 | 电商运营 | 互联网早报 | 站长圈 |
|
||||
| -------- | --------- | ---------- | ------ |
|
||||
| | dianshang | internet | seo |
|
||||
|
||||
</Route>
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue