diff --git a/docs/README.md b/docs/README.md
index c783064b5..6ec0e42a4 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -1019,8 +1019,8 @@ GitHub 官方也提供了一些 RSS:
### nHentai
-
-
+
+
## 二次元
@@ -1563,7 +1563,7 @@ category 列表:
注意: `qttz` 与 `xwdt` 在原网站等价.
-
+
### 华南理工大学
diff --git a/router.js b/router.js
index 484fc4a74..0e46ba908 100644
--- a/router.js
+++ b/router.js
@@ -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'));
diff --git a/routes/nhentai/other.js b/routes/nhentai/other.js
index 8f31514b4..4a9cd777a 100644
--- a/routes/nhentai/other.js
+++ b/routes/nhentai/other.js
@@ -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),
};
};
diff --git a/routes/nhentai/search.js b/routes/nhentai/search.js
index 86430dc83..40e4915d0 100644
--- a/routes/nhentai/search.js
+++ b/routes/nhentai/search.js
@@ -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),
};
};
diff --git a/routes/nhentai/util.js b/routes/nhentai/util.js
index b359a54e0..70cdb45ab 100644
--- a/routes/nhentai/util.js
+++ b/routes/nhentai/util.js
@@ -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: `
`,
+ };
+};
+
+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) => `
`;
return {
+ ...simple,
title: $('div#info > h2').text() || $('div#info > h1').text(),
pubDate: new Date($('time').attr('datetime')).toUTCString(),
- guid: `full:${url}`,
description: `
- ${galleryThumbs.length} pages
- ${galleryThumbs.map(renderImg).join('')}
+ ${galleryImgs.length} pages
+ ${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: `
`,
- };
-}