feat(router): 8kcos tag (#7237)

* fix(route):route 8kcosplay: 子路由/category 无法获取

* feat(route):route 8kcosplay: 增加/tag

* 一些修正

* doc:子路由/tag

* style:

* disable pre-commit hook

* fix(route):route 8kcosplay: 最新文章无法获取

* fix(route):route 8kcosplay: 遵循pubDate规范

* style(route):route 8kcosplay: 遵循pubDate规范

* route 8kcosplay: 获取不到页面时不返回item

* Revert "disable pre-commit hook"

This reverts commit d1342b9ea2e422ea03d2fdd096dfa0a383529b7c.

* fix(route):route 8kcosplay: 删除不必要的async

* fix(route):route 8kcosplay: 限制文章全文获取数量

* use @/utils/got

* feat(route):route 8kcosplay: 使用limit query限制文章全文获取数量

* refactor: migrated to v2

Co-authored-by: TonyRL <TonyRL@users.noreply.github.com>
This commit is contained in:
KotoriK 2022-02-25 08:59:52 +08:00 committed by GitHub
parent 08784f181a
commit cefd9573c8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 135 additions and 75 deletions

View File

@ -48,6 +48,10 @@ pageClass: routes
<Route author="KotoriK" example="/8kcos/cat/8kasianidol" path="/8kcos/cat/:cat*" :paramsDesc="['默认值为8kasianidol将目录页面url中 /category/ 后面的部分填入。如https://www.8kcosplay.com/category/8kchineseidol/%e9%a3%8e%e4%b9%8b%e9%a2%86%e5%9f%9f/ 对应的RSS页面为/8kcos/cat/8kchineseidol/%e9%a3%8e%e4%b9%8b%e9%a2%86%e5%9f%9f/。']"/>
### 标签
<Route author="KotoriK" example="/8kcos/tag/cosplay" path="/8kcos/tag/:tag" :paramsDesc="['标签名']"/>
## Asian to lick
### 首页

View File

@ -3465,9 +3465,10 @@ router.get('/dedao/:caty?', lazyloadRouteHandler('./routes/dedao/index'));
// 未名新闻
router.get('/mitbbs/:caty?', lazyloadRouteHandler('./routes/mitbbs/index'));
// 8kcos
router.get('/8kcos/', lazyloadRouteHandler('./routes/8kcos/latest'));
router.get('/8kcos/cat/:cat*', lazyloadRouteHandler('./routes/8kcos/cat'));
// 8kcos migrated to v2
// router.get('/8kcos/', lazyloadRouteHandler('./routes/8kcos/latest'));
// router.get('/8kcos/cat/:cat*', lazyloadRouteHandler('./routes/8kcos/cat'));
// router.get('/8kcos/tag/:tag', lazyloadRouteHandler('./routes/8kcos/tag'));
// 贾真的电商108将
router.get('/jiazhen108', lazyloadRouteHandler('./routes/jiazhen108/index'));

View File

@ -1,17 +0,0 @@
const Cheerio = require('cheerio');
const got = require('got');
async function loadArticle(link) {
const resp = await got(link);
const article = Cheerio.load(resp.body);
const title = article('.entry-title').text();
const entry_children = article('div.entry-content').children().toArray();
const imgs = Cheerio.load(entry_children.shift()).text(); // 去除懒加载代码减少返回体积
const txt = Cheerio.load(entry_children).html();
return {
title,
description: imgs.concat(txt),
pubDate: article('time')[0].attribs.datetime.replace('>', ''),
link,
};
}
module.exports = loadArticle;

View File

@ -1,28 +0,0 @@
const got = require('got');
const Cheerio = require('cheerio');
const { SUB_NAME_PREFIX, SUB_URL } = require('./const');
const loadArticle = require('./article');
module.exports = async (ctx) => {
const { cat = '8kasianidol' } = ctx.params;
const url = `${SUB_URL}category/${cat}/`;
const resp = await got(url);
const $ = Cheerio.load(resp.body);
ctx.state.data = resp.body
? {
title: `${SUB_NAME_PREFIX}-${$('#wrap > div > div > div > div.sec-panel-head > h1 > span').text()}`,
link: url,
item: await Promise.all(
Cheerio.load(resp.body)('#wrap > div > div > div > ul > li.item')
.map((_, e) => {
const { href } = Cheerio.load(e)('h2 > a')[0].attribs;
return ctx.cache.tryGet(href, () => loadArticle(href));
})
.toArray()
),
}
: {
title: `${SUB_NAME_PREFIX}-${cat}`,
link: url,
item: [{ title: '获取失败' }],
};
};

View File

@ -1,27 +0,0 @@
const got = require('got');
const Cheerio = require('cheerio');
const { SUB_NAME_PREFIX, SUB_URL } = require('./const');
const loadArticle = require('./article');
const url = SUB_URL;
module.exports = async (ctx) => {
const response = await got(url);
ctx.state.data = {
title: `${SUB_NAME_PREFIX}-最新`,
link: url,
item: response.body
? await Promise.all(
Cheerio.load(response.body)('#wrap > div > div > div > ul > li.item')
.map((_, e) => {
const { href } = Cheerio.load(e)('div > h2 > a')[0].attribs;
return ctx.cache.tryGet(href, () => loadArticle(href));
})
.toArray()
)
: [
{
title: '获取失败!',
},
],
};
};

24
lib/v2/8kcos/article.js Normal file
View File

@ -0,0 +1,24 @@
const Cheerio = require('cheerio');
const got = require('@/utils/got');
const { parseDate } = require('@/utils/parse-date');
async function loadArticle(link) {
const resp = await got(link);
const article = Cheerio.load(resp.body);
const entryChildren = article('div.entry-content').children();
const imgs = entryChildren
.find('noscript')
.toArray()
.map((e) => e.children[0].data);
const txt = entryChildren
.slice(2)
.toArray()
.map((e) => Cheerio.load(e).html());
return {
title: article('.entry-title').text(),
description: imgs.concat(txt).join(''),
pubDate: parseDate(article('time')[0].attribs.datetime),
link,
};
}
module.exports = loadArticle;

22
lib/v2/8kcos/cat.js Normal file
View File

@ -0,0 +1,22 @@
const got = require('@/utils/got');
const Cheerio = require('cheerio');
const { SUB_NAME_PREFIX, SUB_URL } = require('./const');
const loadArticle = require('./article');
module.exports = async (ctx) => {
const limit = parseInt(ctx.query.limit);
const { cat = '8kasianidol' } = ctx.params;
const url = `${SUB_URL}category/${cat}/`;
const resp = await got(url);
const $ = Cheerio.load(resp.body);
const itemRaw = $('li.item').toArray();
ctx.state.data = {
title: `${SUB_NAME_PREFIX}-${$('span[property=name]:not(.hide)').text()}`,
link: url,
item: await Promise.all(
(limit ? itemRaw.slice(0, limit) : itemRaw).map((e) => {
const { href } = Cheerio.load(e)('h2 > a')[0].attribs;
return ctx.cache.tryGet(href, () => loadArticle(href));
})
),
};
};

23
lib/v2/8kcos/latest.js Normal file
View File

@ -0,0 +1,23 @@
const got = require('@/utils/got');
const Cheerio = require('cheerio');
const { SUB_NAME_PREFIX, SUB_URL } = require('./const');
const loadArticle = require('./article');
const url = SUB_URL;
module.exports = async (ctx) => {
const limit = parseInt(ctx.query.limit);
const response = await got(url);
const itemRaw = Cheerio.load(response.body)('ul.post-loop li.item').toArray();
ctx.state.data = {
title: `${SUB_NAME_PREFIX}-最新`,
link: url,
item:
response.body &&
(await Promise.all(
(limit ? itemRaw.slice(0, limit) : itemRaw).map((e) => {
const { href } = Cheerio.load(e)('h2 > a')[0].attribs;
return ctx.cache.tryGet(href, () => loadArticle(href));
})
)),
};
};

View File

@ -0,0 +1,5 @@
module.exports = {
'/': ['KotoriK'],
'/cat/:cat*': ['KotoriK'],
'/tag/:tag': ['KotoriK'],
};

25
lib/v2/8kcos/radar.js Normal file
View File

@ -0,0 +1,25 @@
module.exports = {
'8kcosplay.com': {
_name: '8KCosplay',
'.': [
{
title: '最新',
docs: 'https://docs.rsshub.app/picture.html#_8kcosplay',
source: ['/'],
target: '/8kcos',
},
{
title: '分类',
docs: 'https://docs.rsshub.app/picture.html#_8kcosplay',
source: ['/category/:cat*'],
target: (params, url) => `/8kcos/cat/${new URL(url).pathname}`,
},
{
title: '标签',
docs: 'https://docs.rsshub.app/picture.html#_8kcosplay',
source: ['/tag/:tag'],
target: '/8kcos/tag/:tag',
},
],
},
};

5
lib/v2/8kcos/router.js Normal file
View File

@ -0,0 +1,5 @@
module.exports = (router) => {
router.get('/', require('./latest'));
router.get('/cat/:cat*', require('./cat'));
router.get('/tag/:tag', require('./tag'));
};

23
lib/v2/8kcos/tag.js Normal file
View File

@ -0,0 +1,23 @@
const got = require('@/utils/got');
const Cheerio = require('cheerio');
const { SUB_NAME_PREFIX, SUB_URL } = require('./const');
const loadArticle = require('./article');
module.exports = async (ctx) => {
const limit = parseInt(ctx.query.limit);
const { tag } = ctx.params;
const url = `${SUB_URL}tag/${tag}/`;
const resp = await got(url);
const $ = Cheerio.load(resp.body);
const itemRaw = $('li.item').toArray();
ctx.state.data = {
title: `${SUB_NAME_PREFIX}-${$('span[property=name]:not(.hide)').text()}`,
link: url,
item: await Promise.all(
(limit ? itemRaw.slice(0, limit) : itemRaw).map((e) => {
const { href } = Cheerio.load(e)('h2 > a')[0].attribs;
return ctx.cache.tryGet(href, () => loadArticle(href));
})
),
};
};