diff --git a/docs/README.md b/docs/README.md index c1d6982b2f..fb0a71cb7b 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1815,6 +1815,16 @@ https://rsshub.app/**nuist**/`bulletin` 或 https://rsshub.app/**nuist**/`bullet +### 北京航空航天大学 + + + +| 综合新闻 | 信息公告 | 学术文化 | 校园风采 | 科教在线 | 媒体北航 | 专题新闻 | 北航人物 | +| -------- | -------- | ------------ | -------- | -------- | -------- | -------- | -------- | +| zonghe | gonggao | xueshuwenhua | fengcai | kejiao | meiti | zhuanti | renwu | + + + ## 传统媒体 ### 央视新闻 diff --git a/lib/router.js b/lib/router.js index f08a217901..ef33fe8273 100644 --- a/lib/router.js +++ b/lib/router.js @@ -674,6 +674,9 @@ router.get('/henu/:type?', require('./routes/universities/henu/news')); // 南开大学 router.get('/nku/jwc/:type?', require('./routes/universities/nku/jwc/index')); +// 北京航空航天大学 +router.get('/buaa/news/:type', require('./routes/universities/buaa/news/index')); + // ifanr router.get('/ifanr/:channel?', require('./routes/ifanr/index')); diff --git a/lib/routes/universities/buaa/news/index.js b/lib/routes/universities/buaa/news/index.js new file mode 100644 index 0000000000..def9401f40 --- /dev/null +++ b/lib/routes/universities/buaa/news/index.js @@ -0,0 +1,67 @@ +const axios = require('../../../../utils/axios'); +const cheerio = require('cheerio'); +const util = require('../utils'); + +module.exports = async (ctx) => { + const type = ctx.params.type; + let title, path; + switch (type) { + case 'zonghe': + title = '综合新闻'; + path = 'zhxw_new.htm'; + break; + case 'zhuanti': + title = '专题新闻'; + path = 'ztxw_new.htm'; + break; + case 'renwu': + title = '北航人物'; + path = 'bhrw.htm'; + break; + case 'fengcai': + title = '校园风采'; + path = 'xyfc_new.htm'; + break; + case 'kejiao': + title = '科教在线'; + path = 'kjzx_new.htm'; + break; + case 'meiti': + title = '媒体北航'; + path = 'mtbh_new.htm'; + break; + case 'gonggao': + title = '信息公告'; + path = 'xxgg_new.htm'; + break; + case 'xueshuwenhua': + title = '学术文化'; + path = 'xsjwhhd_new.htm'; + break; + default: + title = '综合新闻'; + path = 'zhxw_new.htm'; + } + + const response = await axios({ + method: 'get', + url: 'https://news.buaa.edu.cn/' + path, + headers: { + Referer: 'https://news.buaa.edu.cn', + }, + }); + + const data = response.data; + + const $ = cheerio.load(data); + const list = $('.mainleft > .listlefttop > .listleftop1').get(); + + const result = await util.ProcessFeed(list, ctx.cache); + + ctx.state.data = { + title: '北航新闻 - ' + title, + link: 'https://news.buaa.edu.cn/' + path, + description: '北京航空航天大学新闻网 - ' + title, + item: result, + }; +}; diff --git a/lib/routes/universities/buaa/utils.js b/lib/routes/universities/buaa/utils.js new file mode 100644 index 0000000000..d0ad410dc4 --- /dev/null +++ b/lib/routes/universities/buaa/utils.js @@ -0,0 +1,66 @@ +const axios = require('../../../utils/axios'); +const cheerio = require('cheerio'); +const url = require('url'); + +// 完整文章页 +async function load(link) { + const response = await axios.get(link); + const $ = cheerio.load(response.data); + + // 解析日期 + const date = new Date( + $('span.ri') + .text() + .match(/\d{4}-\d{2}-\d{2}/) + ); + const timeZone = 8; + const serverOffset = date.getTimezoneOffset() / 60; + const pubDate = new Date(date.getTime() - 60 * 60 * 1000 * (timeZone + serverOffset)).toUTCString(); + + // 还原图片地址 + $('img').each((index, elem) => { + const $elem = $(elem); + const src = $elem.attr('src'); + if (src && src !== '') { + $elem.attr('src', `https://news.buaa.edu.cn${src}`); + } + }); + + // 提取内容 + const description = $('.newsleftconbox > #vsb_content').html(); + + return { description, pubDate }; +} + +const ProcessFeed = async (list, caches) => { + const host = 'https://news.buaa.edu.cn'; + + return await Promise.all( + list.map(async (item) => { + const $ = cheerio.load(item); + + const $title = $('h2 > a'); + // 还原相对链接为绝对链接 + const itemUrl = url.resolve(host, $title.attr('href')); + + // 列表上提取到的信息 + const single = { + title: $title.text(), + link: itemUrl, + author: '北航新闻网', + guid: itemUrl, + }; + + // 使用tryGet方法从缓存获取内容。 + // 当缓存中无法获取到链接内容的时候,则使用load方法加载文章内容。 + const other = await caches.tryGet(itemUrl, async () => await load(itemUrl)); + + // 合并解析后的结果集作为该篇文章最终的输出结果 + return Promise.resolve(Object.assign({}, single, other)); + }) + ); +}; + +module.exports = { + ProcessFeed, +};