nhentai: added simple mode (#1191)
* nhentai: added simple mode * nhentai: detail limit & deleted console.log
This commit is contained in:
parent
526f47fc9c
commit
b50f40ab7f
|
|
@ -1019,8 +1019,8 @@ GitHub 官方也提供了一些 RSS:
|
|||
|
||||
### nHentai
|
||||
|
||||
<route name="分类筛选" author="MegrezZhu" example="/nhentai/language/chinese" path="/nhentai/:key/:keyword" :paramsDesc="['筛选条件,可选: parody, character, tag, artist, group, language, category','筛选值']" />
|
||||
<route name="高级搜索" author="MegrezZhu" example="/nhentai/search/language%3Ajapanese+-scat+-yaoi+-guro+-%22mosaic+censorship%22" path="/nhentai/search/:keyword" :paramsDesc="['用于搜索的关键词。可在原网站搜索后复制 q= 后面的内容,也可直接输入,但空格等特殊符号是否会转换取决于浏览器和阅读器的实现。用法详见[官网](https://nhentai.net/info/)']" />
|
||||
<route name="分类筛选" author="MegrezZhu" example="/nhentai/language/chinese" path="/nhentai/:key/:keyword/:mode?" :paramsDesc="['筛选条件,可选: parody, character, tag, artist, group, language, category','筛选值', '模式,`simple`为仅封面,`detail`会包括本子每一页,但对服务器负载大。默认为`simple`']" />
|
||||
<route name="高级搜索" author="MegrezZhu" example="/nhentai/search/language%3Ajapanese+-scat+-yaoi+-guro+-%22mosaic+censorship%22" path="/nhentai/search/:keyword/:mode?" :paramsDesc="['用于搜索的关键词。可在原网站搜索后复制 q= 后面的内容,也可直接输入,但空格等特殊符号是否会转换取决于浏览器和阅读器的实现。用法详见[官网](https://nhentai.net/info/)', '模式,`simple`为仅封面,`detail`会包括本子每一页,但对服务器负载大。默认为`simple`']" />
|
||||
|
||||
## 二次元
|
||||
|
||||
|
|
@ -1563,7 +1563,7 @@ category 列表:
|
|||
注意: `qttz` 与 `xwdt` 在原网站等价.
|
||||
|
||||
</route>
|
||||
|
||||
|
||||
### 华南理工大学
|
||||
|
||||
<route name="教务处新闻动态" author="KeNorizon" example="/scut/jwc/1" path="/scut/jwc/:category?" :paramsDesc="['新闻动态分类, 可选, 默认为 `1`']">
|
||||
|
|
|
|||
|
|
@ -744,8 +744,8 @@ router.get('/youku/channel/:channelId/:embed?', require('./routes/youku/channel'
|
|||
router.get('/oilprice/:area', require('./routes/oilprice'));
|
||||
|
||||
// nHentai
|
||||
router.get('/nhentai/search/:keyword', require('./routes/nhentai/search'));
|
||||
router.get('/nhentai/:key/:keyword', require('./routes/nhentai/other'));
|
||||
router.get('/nhentai/search/:keyword/:mode?', require('./routes/nhentai/search'));
|
||||
router.get('/nhentai/:key/:keyword/:mode?', require('./routes/nhentai/other'));
|
||||
|
||||
// 龙腾网
|
||||
router.get('/ltaaa/:type?', require('./routes/ltaaa/main'));
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
const { getList, getDetailWithCache } = require('./util');
|
||||
const { getSimple, getDetails } = require('./util');
|
||||
|
||||
const supportedKeys = ['parody', 'character', 'tag', 'artist', 'group', 'language', 'category'];
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const { keyword, key } = ctx.params;
|
||||
const { keyword, key, mode } = ctx.params;
|
||||
const isSimple = mode !== 'detail';
|
||||
|
||||
if (supportedKeys.indexOf(key) === -1) {
|
||||
ctx.state.data = {
|
||||
title: 'nHentai - unsupported',
|
||||
|
|
@ -11,13 +13,12 @@ module.exports = async (ctx) => {
|
|||
return;
|
||||
}
|
||||
|
||||
const list = await getList(`https://nhentai.net/${key}/${keyword.toLowerCase().replace(' ', '-')}`);
|
||||
const details = await Promise.all(list.map(getDetailWithCache.bind(null, ctx.cache)));
|
||||
const simples = await getSimple(`https://nhentai.net/${key}/${keyword.toLowerCase().replace(' ', '-')}`);
|
||||
|
||||
ctx.state.data = {
|
||||
title: `nHentai - ${key} - ${keyword}`,
|
||||
link: 'https://nhentai.net',
|
||||
description: 'hentai',
|
||||
item: details,
|
||||
item: isSimple ? simples : await getDetails(ctx.cache, simples),
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,14 +1,15 @@
|
|||
const { getList, getDetailWithCache } = require('./util');
|
||||
const { getSimple, getDetails } = require('./util');
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const { keyword } = ctx.params;
|
||||
const list = await getList(`https://nhentai.net/search/?q=${keyword}`);
|
||||
const details = await Promise.all(list.map(getDetailWithCache.bind(null, ctx.cache)));
|
||||
const { keyword, mode } = ctx.params;
|
||||
const isSimple = mode !== 'detail';
|
||||
|
||||
const simples = await getSimple(`https://nhentai.net/search/?q=${keyword}`);
|
||||
|
||||
ctx.state.data = {
|
||||
title: `nHentai - search - ${keyword}`,
|
||||
link: 'https://nhentai.net',
|
||||
description: 'hentai',
|
||||
item: details,
|
||||
item: isSimple ? simples : await getDetails(ctx.cache, simples),
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -2,66 +2,50 @@ const { resolve } = require('url');
|
|||
const cheerio = require('cheerio');
|
||||
const axios = require('../../utils/axios');
|
||||
|
||||
exports.getList = async (url) => {
|
||||
exports.getSimple = async (url) => {
|
||||
const { data } = await axios.get(url);
|
||||
const $ = cheerio.load(data);
|
||||
|
||||
return $('.gallery a.cover')
|
||||
.map((_, ele) => createResult($, ele))
|
||||
.get();
|
||||
.map((_, ele) => parseSimpleDetail($(ele)))
|
||||
.toArray();
|
||||
};
|
||||
|
||||
exports.getDetail = async (url) => {
|
||||
const { data } = await axios.get(url);
|
||||
const MAX_DETAIL = 5;
|
||||
exports.getDetails = async (cache, simples) => Promise.all(simples.slice(0, MAX_DETAIL).map((simple) => cache.tryGet(simple.link, () => getDetail(simple), 24 * 60 * 60)));
|
||||
|
||||
const parseSimpleDetail = ($ele) => {
|
||||
const link = resolve('https://nhentai.net', $ele.attr('href'));
|
||||
const thumb = $ele.children('img');
|
||||
const thumbSrc = thumb.attr('data-src') || thumb.attr('src');
|
||||
const highResoThumbSrc = thumbSrc.replace('thumb', '1').replace('t.nhentai.net', 'i.nhentai.net');
|
||||
return {
|
||||
title: $ele.children('.caption').text(),
|
||||
link,
|
||||
pubDate: new Date().toUTCString(), // 要获得准确时间需要对每个本子都请求一遍,很麻烦
|
||||
description: `<img referrerpolicy="no-referrer" src="${highResoThumbSrc}" />`,
|
||||
};
|
||||
};
|
||||
|
||||
const getDetail = async (simple) => {
|
||||
const { link } = simple;
|
||||
const { data } = await axios.get(link);
|
||||
const $ = cheerio.load(data);
|
||||
|
||||
// thumb to high-quality
|
||||
let galleryThumbs = $('.gallerythumb img')
|
||||
const galleryImgs = $('.gallerythumb img')
|
||||
.map((_, ele) => resolve('https://nhentai.net', $(ele).attr('data-src')))
|
||||
.get();
|
||||
galleryThumbs = galleryThumbs.map((src) => src.replace(/(.+)(\d+)t\.(.+)/, (_, p1, p2, p3) => `${p1}${p2}.${p3}`));
|
||||
galleryThumbs = galleryThumbs.map((src) => src.replace('t.nhentai.net', 'i.nhentai.net'));
|
||||
.get()
|
||||
.map((src) => src.replace(/(.+)(\d+)t\.(.+)/, (_, p1, p2, p3) => `${p1}${p2}.${p3}`)) // thumb to high-quality
|
||||
.map((src) => src.replace('t.nhentai.net', 'i.nhentai.net'));
|
||||
|
||||
const renderImg = (src) => `<img referrerpolicy="no-referrer" src="${src}" /><br />`;
|
||||
return {
|
||||
...simple,
|
||||
title: $('div#info > h2').text() || $('div#info > h1').text(),
|
||||
pubDate: new Date($('time').attr('datetime')).toUTCString(),
|
||||
guid: `full:${url}`,
|
||||
description: `
|
||||
<h1>${galleryThumbs.length} pages</h1>
|
||||
${galleryThumbs.map(renderImg).join('')}
|
||||
<h1>${galleryImgs.length} pages</h1>
|
||||
${galleryImgs.map(renderImg).join('')}
|
||||
`.trim(),
|
||||
};
|
||||
};
|
||||
|
||||
exports.getDetailWithCache = async (cache, info) => {
|
||||
const cached = await cache.get(`full:${info.link}`);
|
||||
if (cached) {
|
||||
return {
|
||||
...info,
|
||||
...cached,
|
||||
};
|
||||
} else {
|
||||
const detail = await exports.getDetail(info.link);
|
||||
cache.set(`full:${info.link}`, detail);
|
||||
return {
|
||||
...info,
|
||||
...detail,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
function createResult($, ele) {
|
||||
const link = resolve('https://nhentai.net', $(ele).attr('href'));
|
||||
const thumbImg = $(ele).children('img');
|
||||
const thumbSrc = thumbImg.attr('data-src') || thumbImg.attr('src');
|
||||
return {
|
||||
title: $(ele)
|
||||
.children('.caption')
|
||||
.text(),
|
||||
link,
|
||||
guid: link,
|
||||
pubDate: new Date().toUTCString(), // 要获得准确时间需要对每个本子都请求一遍,很麻烦
|
||||
description: `<img referrerpolicy="no-referrer" src="${thumbSrc.replace('thumb', 'cover')}" />`,
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue