diff --git a/docs/README.md b/docs/README.md index e7110af380..523e446f0a 100644 --- a/docs/README.md +++ b/docs/README.md @@ -2506,6 +2506,18 @@ Example: `https://store.steampowered.com/search/?specials=1&term=atelier` 中的 +### 爱思想 + + + + + +| 文章点击排行 | 文章推荐排行 | 最近更新文章 | +| ------------ | ------------ | ------------ | +| 1 | 10 | 11 | + + + ## 政务消息 ### 中国驻外使领馆 diff --git a/lib/router.js b/lib/router.js index 60f9b15fe5..ff3b1f9392 100644 --- a/lib/router.js +++ b/lib/router.js @@ -1045,6 +1045,10 @@ router.get('/gaoqing/latest', require('./routes/gaoqing/latest')); // 轻小说文库 router.get('/wenku8/chapter/:id', require('./routes/wenku8/chapter')); +// 爱思想 +router.get('/aisixiang/column/:id', require('./routes/aisixiang/column')); +router.get('/aisixiang/ranking/:type?/:range?', require('./routes/aisixiang/ranking')); + // LeetCode router.get('/leetcode/articles', require('./routes/leetcode/articles')); diff --git a/lib/routes/aisixiang/column.js b/lib/routes/aisixiang/column.js new file mode 100644 index 0000000000..c2c1068e43 --- /dev/null +++ b/lib/routes/aisixiang/column.js @@ -0,0 +1,39 @@ +const axios = require('../../utils/axios'); +const cheerio = require('cheerio'); +const iconv = require('iconv-lite'); + +const util = require('./utils'); + +module.exports = async (ctx) => { + const { id } = ctx.params; + + const host = `http://www.aisixiang.com/data/search.php?lanmu=${id}`; + + const response = await axios.get(host, { + responseType: 'arraybuffer', + }); + + response.data = iconv.decode(response.data, 'gbk'); + + const $ = cheerio.load(response.data); + + const list = $('.search_list > ul > li > a:nth-child(2)') + .slice(0, 10) + .get(); + + const columnName = $('.search_list > ul > li:nth-child(1) > a:nth-child(1)').text(); + + const items = await Promise.all( + list.map(async (e) => { + const link = $(e).attr('href'); + return await ctx.cache.tryGet(link, async () => await util.ProcessFeed(link)); + }) + ); + + ctx.state.data = { + title: `爱思想栏目 - ${columnName}`, + link: host, + description: `爱思想栏目 - ${columnName}`, + item: items, + }; +}; diff --git a/lib/routes/aisixiang/ranking.js b/lib/routes/aisixiang/ranking.js new file mode 100644 index 0000000000..f6b9fe2db1 --- /dev/null +++ b/lib/routes/aisixiang/ranking.js @@ -0,0 +1,39 @@ +const axios = require('../../utils/axios'); +const cheerio = require('cheerio'); +const iconv = require('iconv-lite'); + +const util = require('./utils'); + +module.exports = async (ctx) => { + const { type = 1, range = 1 } = ctx.params; + + const host = `http://www.aisixiang.com/toplist/index.php?id=${type}&period=${range}`; + + const response = await axios.get(host, { + responseType: 'arraybuffer', + }); + + response.data = iconv.decode(response.data, 'gbk'); + + const $ = cheerio.load(response.data); + + const list = $('.tops_list > .tips > a') + .slice(0, 10) + .get(); + + const columnName = $('.tops_text > h3')[0].firstChild.nodeValue; + + const items = await Promise.all( + list.map(async (e) => { + const link = $(e).attr('href'); + return await ctx.cache.tryGet(link, async () => await util.ProcessFeed(link)); + }) + ); + + ctx.state.data = { + title: `爱思想 - ${columnName}`, + link: host, + description: `爱思想 - ${columnName}`, + item: items, + }; +}; diff --git a/lib/routes/aisixiang/utils.js b/lib/routes/aisixiang/utils.js new file mode 100644 index 0000000000..05bed0a030 --- /dev/null +++ b/lib/routes/aisixiang/utils.js @@ -0,0 +1,46 @@ +const cheerio = require('cheerio'); +const iconv = require('iconv-lite'); +const axios = require('../../utils/axios'); +const date = require('../../utils/date'); + +const ProcessFeed = async (link) => { + const id = link + .split('/') + .pop() + .split('.')[0]; + + let response = await axios.get(`http://www.aisixiang.com/data/view_json.php?id=${id}`, { + responseType: 'arraybuffer', + }); + + const description = JSON.parse(iconv.decode(response.data, 'gbk')).content; + + response = await axios.get(`http://www.aisixiang.com${link}`, { + responseType: 'arraybuffer', + }); + + response.data = iconv.decode(response.data, 'gbk'); + + const $ = cheerio.load(response.data); + + const title = $('.show_text > h3').text(); + + const pubDate = date( + $('.show_text > .info') + .text() + .split(':') + .pop(), + 8 + ); + + return { + title: title.split('/')[1] || title, + author: title.split('/')[0] || '', + description, + pubDate, + }; +}; + +module.exports = { + ProcessFeed, +};