diff --git a/docs/bbs.md b/docs/bbs.md index ddcd8d39d3..bce1e8e559 100644 --- a/docs/bbs.md +++ b/docs/bbs.md @@ -14,6 +14,12 @@ pageClass: routes +## Discuz + +### 通用子版块 + + + ## MCBBS ### 版块 diff --git a/lib/router.js b/lib/router.js index b73003a598..e3a1a5942a 100644 --- a/lib/router.js +++ b/lib/router.js @@ -2138,4 +2138,7 @@ router.get('/gbcc/trust', require('./routes/gbcc/trust')); // Associated Press router.get('/apnews/topics/:topic', require('./routes/apnews/topics')); +// discuz +router.get('/discuz/:link', require('./routes/discuz/discuz')); + module.exports = router; diff --git a/lib/routes/discuz/discuz.js b/lib/routes/discuz/discuz.js new file mode 100644 index 0000000000..07f9a3454e --- /dev/null +++ b/lib/routes/discuz/discuz.js @@ -0,0 +1,20 @@ +const buildData = require('@/utils/common-config'); +module.exports = async (ctx) => { + const link = ctx.params.link; + ctx.state.data = await buildData({ + link, + url: link, + title: `%title%`, + params: { + title: `$('head > title').text()`, + }, + item: { + item: 'tbody[id^="normalthread"] tr', + title: `$('a.xst').text()`, + link: `$('a.xst').attr('href')`, + description: `$('a.xst').text()`, + pubDate: `require('@/utils/date')($('td.by:nth-child(3) em span').last().text())`, + guid: `$('a.xst').attr('href')`, + }, + }); +}; diff --git a/lib/utils/common-config.js b/lib/utils/common-config.js index 6ee5dff096..5ca9df32d1 100644 --- a/lib/utils/common-config.js +++ b/lib/utils/common-config.js @@ -1,5 +1,6 @@ const cheerio = require('cheerio'); const got = require('@/utils/got'); +const iconv = require('iconv-lite'); // eslint-disable-next-line no-unused-vars const date = require('@/utils/date'); @@ -38,8 +39,17 @@ function getProp(data, prop, $) { } async function buildData(data) { - const response = (await got.get(data.url)).data; - const $ = cheerio.load(response); + const response = await got.get(data.url); + const contentType = response.headers['content-type'] || ''; + // 若没有指定编码,则默认utf-8 + let charset = 'utf-8'; + for (const attr of contentType.split(';')) { + if (attr.indexOf('charset=') >= 0) { + charset = attr.split('=').pop(); + } + } + const responseData = charset === 'utf-8' ? response.data : iconv.decode((await got.get({ url: data.url, responseType: 'buffer' })).data, charset); + const $ = cheerio.load(responseData); const $item = $(data.item.item); // 这里应该是可以通过参数注入一些代码的,不过应该无伤大雅 return {