diff --git a/docs/university.md b/docs/university.md index cb0dd2754..2d712fb21 100644 --- a/docs/university.md +++ b/docs/university.md @@ -114,7 +114,7 @@ pageClass: routes ### 信科公告通知 - + | 全部 | 学院通知 | 人事通知 | 教务通知 | 学工通知 | 科研通知 | 财务通知 | 工会通知 | 院友通知 | | -- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | @@ -124,15 +124,15 @@ pageClass: routes ### 每周一推 - 中国政治学研究中心 - + ### 生命科学学院近期讲座 - + ### 北大未名 BBS 全站十大 - + ::: warning 注意 @@ -142,9 +142,19 @@ pageClass: routes +### 学生就业指导服务中心 + + + +| xwrd | tzgg | zpxx | gfjgxx | sxxx | cyxx | +| ---- | ---- | ---- | ------ | ---- | ---- | +| 新闻热点 | 通知公告 | 招聘信息 | 国防军工信息 | 实习信息 | 创业信息 | + + + ### 人事处 - + ::: tip 提示 @@ -156,6 +166,10 @@ pageClass: routes +### 研究生招生网 + + + ## 北京航空航天大学 ### 北京航空航天大学 diff --git a/lib/router.js b/lib/router.js index 9976295fc..76957d5be 100644 --- a/lib/router.js +++ b/lib/router.js @@ -563,11 +563,12 @@ router.get('/lit/tw/:name?', lazyloadRouteHandler('./routes/universities/lit/tw' router.get('/thu/career', lazyloadRouteHandler('./routes/universities/thu/career')); router.get('/thu/:type', lazyloadRouteHandler('./routes/universities/thu/index')); -// 北京大学 -router.get('/pku/eecs/:type?', lazyloadRouteHandler('./routes/universities/pku/eecs')); -router.get('/pku/rccp/mzyt', lazyloadRouteHandler('./routes/universities/pku/rccp/mzyt')); -router.get('/pku/cls/lecture', lazyloadRouteHandler('./routes/universities/pku/cls/lecture')); -router.get('/pku/bbs/hot', lazyloadRouteHandler('./routes/universities/pku/bbs/hot')); +// 北京大学 migrated to v2 +// router.get('/pku/eecs/:type?', lazyloadRouteHandler('./routes/universities/pku/eecs')); +// router.get('/pku/rccp/mzyt', lazyloadRouteHandler('./routes/universities/pku/rccp/mzyt')); +// router.get('/pku/cls/lecture', lazyloadRouteHandler('./routes/universities/pku/cls/lecture')); +// router.get('/pku/bbs/hot', lazyloadRouteHandler('./routes/universities/pku/bbs/hot')); +// router.get('/pku/scc/recruit/:type?', lazyloadRouteHandler('./routes/universities/pku/scc/recruit')); // 上海海事大学 router.get('/shmtu/www/:type', lazyloadRouteHandler('./routes/universities/shmtu/www')); @@ -2640,8 +2641,8 @@ router.get('/scutyjs', lazyloadRouteHandler('./routes/universities/scut/scutyjs' // 华南农业大学研究生院通知公告 router.get('/scauyjs', lazyloadRouteHandler('./routes/universities/scauyjs/scauyjs')); -// 北京大学研究生招生网通知公告 -router.get('/pkuyjs', lazyloadRouteHandler('./routes/universities/pku/pkuyjs')); +// 北京大学研究生招生网通知公告 migrated to v2 +// router.get('/pkuyjs', lazyloadRouteHandler('./routes/universities/pku/pkuyjs')); // 北京理工大学研究生通知公告 router.get('/bityjs', lazyloadRouteHandler('./routes/universities/bit/bityjs')); diff --git a/lib/routes/universities/pku/eecs.js b/lib/routes/universities/pku/eecs.js deleted file mode 100644 index 0c4932c5b..000000000 --- a/lib/routes/universities/pku/eecs.js +++ /dev/null @@ -1,41 +0,0 @@ -const got = require('@/utils/got'); -const cheerio = require('cheerio'); - -module.exports = async (ctx) => { - const host = 'http://eecs.pku.edu.cn/'; - - let type = ctx.params && ctx.params.type; - if (type === undefined) { - type = '0'; - } - - const response = await got({ - method: 'get', - url: host + 'Survey/Notice/?Mtitle=' + type, - headers: { - Referer: host, - }, - }); - - const $ = cheerio.load(response.data); - const text = $('.hvr-shutter-out-vertical').slice(0, 10); - - ctx.state.data = { - title: '北大信科通知', - link: host + 'Survey/Notice/?Mtitle=' + type, - description: '北大信科 公告通知', - item: - text && - text - .map((index, item) => { - item = $(item); - return { - title: item.find('p').text(), - link: host + 'Survey/Notice/' + item.attr('href'), - description: item.find('p').text(), - pubDate: item.find('em').text(), - }; - }) - .get(), - }; -}; diff --git a/lib/routes/universities/pku/pkuyjs.js b/lib/routes/universities/pku/pkuyjs.js deleted file mode 100644 index 6ad3dc0a5..000000000 --- a/lib/routes/universities/pku/pkuyjs.js +++ /dev/null @@ -1,23 +0,0 @@ -const got = require('@/utils/got'); -const cheerio = require('cheerio'); - -module.exports = async (ctx) => { - const link = 'https://admission.pku.edu.cn/zsxx/sszs/index.htm'; - const response = await got.get(link); - const $ = cheerio.load(response.data); - const list = $('.zsxx_cont_list li').slice(0, 10); - - ctx.state.data = { - title: '北京大学研究生院', - link, - description: '北京大学研究生院通知公告', - item: - list && - list - .map((index, item) => { - item = $(item); - return { title: item.find('li a').text(), description: item.find('li a').text(), link: item.find('li a').attr('href') }; - }) - .get(), - }; -}; diff --git a/lib/routes/universities/pku/rccp/mzyt.js b/lib/routes/universities/pku/rccp/mzyt.js deleted file mode 100644 index e222f3abe..000000000 --- a/lib/routes/universities/pku/rccp/mzyt.js +++ /dev/null @@ -1,33 +0,0 @@ -const got = require('@/utils/got'); -const cheerio = require('cheerio'); - -const baseUrl = 'http://www.rccp.pku.edu.cn/mzyt/'; - -module.exports = async (ctx) => { - const response = await got({ - method: 'get', - url: baseUrl, - }); - - const $ = cheerio.load(response.data); - ctx.state.data = { - title: `每周一推 - 北京大学中国政治学研究中心`, - link: baseUrl, - description: `北京大学中国政治学研究中心,北大中国政治学研究中心,北大政治学研究中心,中国政治学研究中心,政治学研究中心,政治学,北大政治学,北京大学,俞可平 - 北京大学中国政治学研究中心官方网站:www.rccp.pku.edu.cn 。 - 北京大学中国政治学研究中心微信公众平台:“北大政治学”(微信号:PKURCCP)`, - item: $('li.list') - .map((index, item) => ({ - title: $(item).find('a').text().trim(), - description: '', - pubDate: $(item) - .find('span') - .first() - .text() - .match(/\d{4}-\d{2}-\d{2}/g)[0], - - link: baseUrl + $(item).find('a').attr('href'), - })) - .get(), - }; -}; diff --git a/lib/routes/universities/pku/bbs/hot.js b/lib/v2/pku/bbs/hot.js similarity index 78% rename from lib/routes/universities/pku/bbs/hot.js rename to lib/v2/pku/bbs/hot.js index 14c05e799..551079662 100644 --- a/lib/routes/universities/pku/bbs/hot.js +++ b/lib/v2/pku/bbs/hot.js @@ -1,14 +1,8 @@ const config = require('@/config').value; const cheerio = require('cheerio'); const got = require('@/utils/got'); -const resolveUrl = require('url').resolve; - -function parseDate(text) { - const match = /[0-9 :-]+/.exec(text); - if (match) { - return new Date(match[0]).toUTCString(); - } -} +const { parseDate } = require('@/utils/parse-date'); +const timezone = require('@/utils/timezone'); module.exports = async (ctx) => { const cookie = config.pkubbs.cookie; @@ -21,7 +15,7 @@ module.exports = async (ctx) => { const listItems = $('#list-content .list-item') .map(function () { return { - url: resolveUrl(r.url, $(this).find('> a.link').attr('href')), + url: new URL($(this).find('> a.link').attr('href'), r.url).href, title: $(this).find('.title').text(), }; }) @@ -35,12 +29,13 @@ module.exports = async (ctx) => { try { const r = await got(url, { headers }); const $ = cheerio.load(r.body); + const date = $('.post-card:first-child .sl-triangle-container .down-list span').text() || $('.post-card:first-child .sl-triangle-container .title span').text(); return { title, description: $('.post-card:first-child .content').html(), link: url, guid: url, - pubDate: parseDate($('.post-card:first-child .sl-triangle-container .title span').text()), + pubDate: timezone(parseDate(date, '发表于YYYY-MM-DD HH:mm:ss'), +8), }; } catch (error) { return { diff --git a/lib/routes/universities/pku/cls/lecture.js b/lib/v2/pku/cls/lecture.js similarity index 71% rename from lib/routes/universities/pku/cls/lecture.js rename to lib/v2/pku/cls/lecture.js index 1077862db..a22722624 100644 --- a/lib/routes/universities/pku/cls/lecture.js +++ b/lib/v2/pku/cls/lecture.js @@ -1,14 +1,12 @@ const got = require('@/utils/got'); const cheerio = require('cheerio'); +const { parseDate } = require('@/utils/parse-date'); -const homeUrl = 'http://www.bio.pku.edu.cn/homes/Index/news_jz/7/7.html'; -const baseUrl = 'http://www.bio.pku.edu.cn'; +const homeUrl = 'http://bio.pku.edu.cn/homes/Index/news_jz/7/7.html'; +const baseUrl = 'http://bio.pku.edu.cn'; module.exports = async (ctx) => { - const response = await got({ - method: 'get', - url: homeUrl, - }); + const response = await got(homeUrl); const $ = cheerio.load(response.data); ctx.state.data = { @@ -19,7 +17,7 @@ module.exports = async (ctx) => { .map((index, item) => ({ title: $(item).find('p').text().trim(), description: '日期: ' + $(item).find('span'), // ${item.find('.chair_txt div').find('span').second().text()} - + pubDate: parseDate($(item).find('.date').text()), link: baseUrl + $('a.clearfix').attr('href'), })) .get(), diff --git a/lib/v2/pku/eecs.js b/lib/v2/pku/eecs.js new file mode 100644 index 000000000..3b7277259 --- /dev/null +++ b/lib/v2/pku/eecs.js @@ -0,0 +1,64 @@ +const got = require('@/utils/got'); +const cheerio = require('cheerio'); +const { parseDate } = require('@/utils/parse-date'); + +const { eecsMap } = require('./utils'); + +module.exports = async (ctx) => { + const host = 'https://eecs.pku.edu.cn'; + + let type = ctx.params && parseInt(ctx.params.type); + if (type === undefined) { + type = 0; + } + + const response = await got(host + '/xygk1/ggtz/' + eecsMap.get(type)); + + const $ = cheerio.load(response.data); + let items = $('.hvr-shutter-out-vertical') + .toArray() + .map((item) => { + item = $(item); + return { + title: item.attr('title'), + link: new URL(item.attr('href'), host).href, + pubDate: parseDate(item.find('em').text()), + }; + }); + + items = await Promise.all( + items.map((item) => + ctx.cache.tryGet(item.link, async () => { + const detail = await got(item.link); + const content = cheerio.load(detail.data); + + content('input').remove(); + content('h1').remove(); + content('.con_xq').remove(); + + content('form[name=_newscontent_fromname] img').each((_, i) => { + i = $(i); + if (i.attr('src').startsWith('/')) { + i.attr('src', new URL(i.attr('src'), host).href); + } + }); + content('form[name=_newscontent_fromname] ul li a').each((_, a) => { + a = $(a); + if (a.attr('href').startsWith('/')) { + a.attr('href', new URL(a.attr('href'), host).href); + } + }); + + item.description = content('form[name=_newscontent_fromname]').html(); + return item; + }) + ) + ); + + ctx.state.data = { + title: $('title').text(), + link: host + '/xygk1/ggtz/' + eecsMap.get(type), + description: '北大信科 公告通知', + item: items, + }; +}; diff --git a/lib/v2/pku/maintainer.js b/lib/v2/pku/maintainer.js index de641d1c6..1c261e7c8 100644 --- a/lib/v2/pku/maintainer.js +++ b/lib/v2/pku/maintainer.js @@ -1,3 +1,9 @@ module.exports = { + '/admission/sszs': ['pkuyjs'], + '/bbs/hot': ['wooddance'], + '/cls/lecture': ['TPOB'], + '/eecs/:type?': ['Ir1d'], '/hr/:category?': ['nczitzk'], + '/rccp/mzyt': ['vhxubo'], + '/scc/recruit/:type?': ['DylanXie123'], }; diff --git a/lib/v2/pku/pkuyjs.js b/lib/v2/pku/pkuyjs.js new file mode 100644 index 000000000..245446314 --- /dev/null +++ b/lib/v2/pku/pkuyjs.js @@ -0,0 +1,29 @@ +const got = require('@/utils/got'); +const cheerio = require('cheerio'); +const { parseDate } = require('@/utils/parse-date'); + +module.exports = async (ctx) => { + const link = 'https://admission.pku.edu.cn/zsxx/sszs/index.htm'; + const response = await got(link); + const $ = cheerio.load(response.data); + const list = $('.zsxx_cont_list li'); + + ctx.state.data = { + title: `${$('.twostage_title_C').text()} - ${$('title').text()}`, + link, + description: '北京大学研究生院通知公告', + item: + list && + list + .map((index, item) => { + item = $(item); + return { + title: item.find('li a').text(), + description: item.find('li a').text(), + link: item.find('li a').attr('href'), + pubDate: parseDate(item.find('.zsxxCont_list_time').text()), + }; + }) + .get(), + }; +}; diff --git a/lib/v2/pku/radar.js b/lib/v2/pku/radar.js index 5de8bc529..4867d8e8e 100644 --- a/lib/v2/pku/radar.js +++ b/lib/v2/pku/radar.js @@ -1,6 +1,73 @@ module.exports = { 'pku.edu.cn': { _name: '北京大学', + admission: [ + { + title: '硕士招生', + docs: 'https://docs.rsshub.app/university.html#bei-jing-da-xue', + source: ['/zsxx/sszs/index.htm', '/'], + target: '/pku/admission/sszs', + }, + ], + bbs: [ + { + title: '北大未名 BBS 全站十大', + docs: 'https://docs.rsshub.app/university.html#bei-jing-da-xue', + source: ['/v2/hot-topic.php', '/'], + target: '/pku/bbs/hot', + }, + ], + bio: [ + { + title: '生命科学学院近期讲座', + docs: 'https://docs.rsshub.app/university.html#bei-jing-da-xue', + source: ['/homes/Index/news_jz/7/7.html', '/'], + target: '/pku/cls/lecture', + }, + ], + eecs: [ + { + title: '信科公告通知', + docs: 'https://docs.rsshub.app/university.html#bei-jing-da-xue', + source: ['/xygk1/ggtz/:type', '/xygk1/ggtz.htm', '/'], + target: (params) => { + let type = params.type; + switch (type) { + case 'qb.htm': + type = 0; + break; + case 'xytz.htm': + type = 1; + break; + case 'rstz.htm': + type = 2; + break; + case 'jwtz.htm': + type = 6; + break; + case 'xgtz.htm': + type = 8; + break; + case 'kytz.htm': + type = 7; + break; + case 'cwtz.htm': + type = 5; + break; + case 'ghtz.htm': + type = 3; + break; + case 'yytz.htm': + type = 4; + break; + default: + type = 0; + break; + } + return `/pku/eecs/${type}`; + }, + }, + ], hr: [ { title: '人事处', @@ -9,5 +76,47 @@ module.exports = { target: '/pku/hr/:category?', }, ], + 'www.rccp': [ + { + title: '每周一推 - 中国政治学研究中心', + docs: 'https://docs.rsshub.app/university.html#bei-jing-da-xue-ren-shi-chu', + source: ['/'], + target: '/pku/rccp/mzyt', + }, + ], + scc: [ + { + title: '学生就业指导服务中心', + docs: 'https://docs.rsshub.app/university.html#bei-jing-da-xue-ren-shi-chu', + source: ['/*path'], + target: (params) => { + let type; + switch (params.path) { + case 'home!newsHome.action?category=12': + type = 'xwrd'; + break; + case 'home!newsHome.action?category=13': + type = 'tzgg'; + break; + case 'home!recruit.action?category=1&jobType=110001': + type = 'zpxx'; + break; + case 'home!recruitList.action?category=1&jobType=110002': + type = 'gfjgxx'; + break; + case 'home!recruitList.action?category=2': + type = 'sxxx'; + break; + case 'home!newsHome.action?category=11': + type = 'cyxx'; + break; + default: + type = 'zpxx'; + break; + } + return `/pku/scc/recruit/${type}`; + }, + }, + ], }, }; diff --git a/lib/v2/pku/rccp/mzyt.js b/lib/v2/pku/rccp/mzyt.js new file mode 100644 index 000000000..9d815a32c --- /dev/null +++ b/lib/v2/pku/rccp/mzyt.js @@ -0,0 +1,23 @@ +const got = require('@/utils/got'); +const cheerio = require('cheerio'); +const { parseDate } = require('@/utils/parse-date'); +const baseUrl = 'https://www.rccp.pku.edu.cn/mzyt/'; + +module.exports = async (ctx) => { + const response = await got(baseUrl); + + const $ = cheerio.load(response.data); + ctx.state.data = { + title: '每周一推 - 北京大学中国政治学研究中心', + link: baseUrl, + description: $('meta[name="description"]').attr('content'), + item: $('li.list') + .map((index, item) => ({ + title: $(item).find('a').text().trim(), + description: '', + pubDate: parseDate($(item).find('span').first().text(), '[YYYY-MM-DD]'), + link: baseUrl + $(item).find('a').attr('href'), + })) + .get(), + }; +}; diff --git a/lib/v2/pku/router.js b/lib/v2/pku/router.js index 6f22cd81e..c371728e9 100644 --- a/lib/v2/pku/router.js +++ b/lib/v2/pku/router.js @@ -1,3 +1,9 @@ module.exports = function (router) { + router.get('/admission/sszs', require('./pkuyjs')); + router.get('/bbs/hot', require('./bbs/hot')); + router.get('/cls/lecture', require('./cls/lecture')); + router.get('/eecs/:type?', require('./eecs')); router.get('/hr/:category?', require('./hr')); + router.get('/rccp/mzyt', require('./rccp/mzyt')); + router.get('/scc/recruit/:type?', require('./scc/recruit')); }; diff --git a/lib/v2/pku/scc/recruit.js b/lib/v2/pku/scc/recruit.js new file mode 100644 index 000000000..5a8b5533e --- /dev/null +++ b/lib/v2/pku/scc/recruit.js @@ -0,0 +1,58 @@ +const got = require('@/utils/got'); +const cheerio = require('cheerio'); +const { parseDate } = require('@/utils/parse-date'); + +const arr = { + xwrd: 'home!newsHome.action?category=12', + tzgg: 'home!newsHome.action?category=13', + zpxx: 'home!recruit.action?category=1&jobType=110001', + gfjgxx: 'home!recruitList.action?category=1&jobType=110002', + sxxx: 'home!recruitList.action?category=2', + cyxx: 'home!newsHome.action?category=11', +}; +const baseUrl = 'https://scc.pku.edu.cn/'; + +module.exports = async (ctx) => { + const type = ctx.params.type ?? 'zpxx'; + const rootUrl = baseUrl + arr[type]; + + const list_response = await got(rootUrl); + const $ = cheerio.load(list_response.data); + + const feed_title = $('h2.category').text(); + + const list = $('div#articleList-body div.item.clearfix') + .map((_, item) => { + item = $(item); + const a = item.find('a'); + const date = parseDate(item.find('div.item-date').text()); + return { + title: a.text(), + link: new URL(a.attr('href'), baseUrl), + pubDate: date, + }; + }) + .get(); + + const sorted = list.sort((a, b) => b.pubDate.getTime() - a.pubDate.getTime()).slice(0, 10); + + ctx.state.data = { + title: `北京大学学生就业指导服务中心 - ${feed_title}`, + link: rootUrl, + item: await Promise.all( + sorted.map((item) => + ctx.cache.tryGet(item.link, async () => { + const detail_page = await got(item.link); + const detail = cheerio.load(detail_page.data); + const script = detail('script', 'div#content-div').html(); + if (script !== null) { + const content_route = script.match(/\$\("#content-div"\).load\("(\S+)"\)/)[1]; + const content = await got(new URL(content_route, baseUrl).href); + item.description = content.data; + } + return item; + }) + ) + ), + }; +}; diff --git a/lib/v2/pku/utils.js b/lib/v2/pku/utils.js new file mode 100644 index 000000000..fb3b89527 --- /dev/null +++ b/lib/v2/pku/utils.js @@ -0,0 +1,15 @@ +const eecsMap = new Map([ + [0, 'qb.htm'], + [1, 'xytz.htm'], + [2, 'rstz.htm'], + [6, 'jwtz.htm'], + [8, 'xgtz.htm'], + [7, 'kytz.htm'], + [5, 'cwtz.htm'], + [3, 'ghtz.htm'], + [4, 'yytz.htm'], +]); + +module.exports = { + eecsMap, +};