diff --git a/docs/university.md b/docs/university.md index e7ddddc1cc..7a698d2b2e 100644 --- a/docs/university.md +++ b/docs/university.md @@ -1870,6 +1870,24 @@ type 列表: +## 中国科学技术大学 + +### 官网通知公告 + + + +| 教学类 | 科研类 | 管理类 | 服务类 | +| ------ | ------ | ------ | ------ | +| jx | ky | gl | fw | + +### 教务处通知新闻 + + + +| 信息 | 教学 | 考试 | 交流 | +| -------- | -------- | -------- | -------- | +| info | teaching | exam | exchange | + ## 中国地质大学 (武汉) ### 研究生院综合通知公告 diff --git a/lib/router.js b/lib/router.js index 2816a8af13..ee4cfff800 100644 --- a/lib/router.js +++ b/lib/router.js @@ -670,6 +670,10 @@ router.get('/cas/mesalab/kb', require('./routes/universities/cas/mesalab/kb')); // 中国传媒大学 router.get('/cuc/yz', require('./routes/universities/cuc/yz')); +// 中国科学技术大学 +router.get('/ustc/news/:type?', require('./routes/universities/ustc/index')); +router.get('/ustc/jwc/:type?', require('./routes/universities/ustc/jwc/index')); + // 南京邮电大学 router.get('/njupt/jwc/:type?', require('./routes/universities/njupt/jwc')); diff --git a/lib/routes/universities/ustc/index.js b/lib/routes/universities/ustc/index.js new file mode 100644 index 0000000000..8bbf6ec4f3 --- /dev/null +++ b/lib/routes/universities/ustc/index.js @@ -0,0 +1,93 @@ +const got = require('@/utils/got'); +const cheerio = require('cheerio'); +const url = require('url'); + +const notice_type = { + jx: { title: '中国科学技术大学 - 教学类通知', url: 'https://ustc.edu.cn/tzgg/jxltz.htm' }, + ky: { title: '中国科学技术大学 - 科研类通知', url: 'https://ustc.edu.cn/tzgg/kyltz.htm' }, + gl: { title: '中国科学技术大学 - 管理类通知', url: 'https://ustc.edu.cn/tzgg/glltz.htm' }, + fw: { title: '中国科学技术大学 - 服务类通知', url: 'https://ustc.edu.cn/tzgg/fwltz.htm' }, +}; + +// 对防抓的措施 +async function getCookie(ctx) { + const cache_key = `ustc-cookie-${new Date().toLocaleDateString()}`; + const cached_cookie = await ctx.cache.get(cache_key); + if (cached_cookie) { + return cached_cookie; + } + const { headers } = await got.get('https://ustc.edu.cn/system/resource/code/datainput.jsp', { + headers: { 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36' }, + }); + const cookie = headers['set-cookie'] + .filter((c) => c.match(/(user_trace_token|X_HTTP_TOKEN)/)) + .map((c) => c.split(';')[0]) + .join('; '); + ctx.cache.set(cache_key, cookie); + return cookie; +} + +module.exports = async (ctx) => { + const type = ctx.params.type || 'gl'; + // 发起 HTTP GET 请求 + const response = await got({ + method: 'get', + headers: { + 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36', + cookie: await getCookie(ctx), + }, + url: notice_type[type].url, + }); + + const $ = cheerio.load(response.data); + const list = $('table[portletmode=simpleList] > tbody > tr') + .map(function () { + const child = $(this).children(); + const info = { + title: $(child[1]).find('a').text(), + link: $(child[1]).find('a').attr('href'), + date: new Date($(child[2]).text()).toUTCString(), + }; + return info; + }) + .get(); + + const out = await Promise.all( + list + .filter((item) => item.link) + .map(async (item) => { + const itemUrl = url.resolve(notice_type[type].url, item.link); + if (itemUrl.includes('tzggcontent.jsp') || itemUrl.includes('.ustc.edu.cn')) { + const single = { + title: item.title, + link: itemUrl, + description: item.title, + pubDate: item.date, + }; + return Promise.resolve(single); + } else { + const cache = await ctx.cache.get(itemUrl); + if (cache) { + return Promise.resolve(JSON.parse(cache)); + } + const response = await got.get(itemUrl); + const $ = cheerio.load(response.data); + const single = { + title: $('td[class=title] > span').text(), + link: itemUrl, + description: $('td[class=content]').html(), + pubDate: item.date, + }; + ctx.cache.set(itemUrl, JSON.stringify(single)); + return Promise.resolve(single); + } + }) + ); + + ctx.state.data = { + title: notice_type[type].title, + description: notice_type[type].title, + link: notice_type[type].url, + item: out, + }; +}; diff --git a/lib/routes/universities/ustc/jwc/index.js b/lib/routes/universities/ustc/jwc/index.js new file mode 100644 index 0000000000..f979128d1e --- /dev/null +++ b/lib/routes/universities/ustc/jwc/index.js @@ -0,0 +1,60 @@ +const got = require('@/utils/got'); +const cheerio = require('cheerio'); + +const noticeUrl = 'https://www.teach.ustc.edu.cn/category/notice'; +const noticeType = { teaching: '教学', info: '信息', exam: '考试', exchange: '交流' }; + +module.exports = async (ctx) => { + const type = ctx.params.type || ''; + // 发起 HTTP GET 请求 + const response = await got({ + method: 'get', + headers: { + 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36', + }, + url: `${noticeUrl}${type === '' ? '' : '-' + type}`, + }); + + const $ = cheerio.load(response.data); + const list = $(`${type === '' ? 'ul[class="article-list with-tag"] > li' : 'ul[class=article-list] > li'}`) + .map(function () { + const child = $(this).children(); + const info = { + title: `${type === '' ? $(child[0]).find('a').text() + ' - ' + $(child[1]).find('a').text() : $(child[0]).find('a').text()}`, + link: `${type === '' ? $(child[1]).find('a').attr('href') : $(child[0]).find('a').attr('href')}`, + }; + return info; + }) + .get(); + + const out = await Promise.all( + list + .filter((item) => item.link) + .map(async (item) => { + const itemUrl = item.link; + const cache = await ctx.cache.get(itemUrl); + if (cache) { + return Promise.resolve(JSON.parse(cache)); + } + const response = await got.get(itemUrl); + const $ = cheerio.load(response.data); + const single = { + title: item.title, + link: itemUrl, + description: $('main[class=single]').html(), + pubDate: new Date($('li[class=meta-date]').text()).toUTCString(), + }; + ctx.cache.set(itemUrl, JSON.stringify(single)); + return Promise.resolve(single); + }) + ); + + const desc = type === '' ? '中国科学技术大学教务处 - 通知新闻' : `中国科学技术大学教务处 - ${noticeType[type]}类通知`; + + ctx.state.data = { + title: desc, + description: desc, + link: `${noticeUrl}${type === '' ? '' : '-' + type}`, + item: out, + }; +};