fix(route/sjtu): gs (#12758)
* fix(route/sjtu): gs * Correct "Incomplete URL substring sanitization" * Use built-in etchArticle for Wechat article. * Update lib/v2/sjtu/radar.js * Fix missing semicolon. * Update university.md * refactor: migrate to v2 rename maintainer GitHub ID from `richardchien` to `stdrc` https://github.com/DIYgod/RSSHub/pull/4064 * fix(radar): add default case ---------
This commit is contained in:
parent
4e41f3e67d
commit
b378116a71
|
|
@ -2576,11 +2576,11 @@ jsjxy.hbut.edu.cn 证书链不全,自建 RSSHub 可设置环境变量 NODE_TLS
|
|||
|
||||
### 电子信息与电气工程学院学术动态
|
||||
|
||||
<Route author="HenryQW" example="/sjtu/seiee/academic" path="/sjtu/seiee/academic"/>
|
||||
<Route author="HenryQW" example="/sjtu/seiee/academic" path="/sjtu/seiee/academic" radar="1"/>
|
||||
|
||||
### 电子信息与电气工程学院本科教务办
|
||||
|
||||
<Route author="Polynomia" example="/sjtu/seiee/bjwb/major_select" path="/sjtu/seiee/bjwb/:type" :paramsDesc="['无默认选项']">
|
||||
<Route author="Polynomia" example="/sjtu/seiee/bjwb/major_select" path="/sjtu/seiee/bjwb/:type" :paramsDesc="['无默认选项']" radar="1">
|
||||
|
||||
| 分专业 | 转专业 | 直升研究生 | 交换交流 | 国际办学 |
|
||||
| ------------ | -------------- | ------------ | -------- | ------------- |
|
||||
|
|
@ -2588,19 +2588,9 @@ jsjxy.hbut.edu.cn 证书链不全,自建 RSSHub 可设置环境变量 NODE_TLS
|
|||
|
||||
</Route>
|
||||
|
||||
### 研究生通知公告
|
||||
|
||||
<Route author="mzr1996" example="/sjtu/gs/tzgg/pyxx" path="/sjtu/gs/tzgg/:type?" :paramsDesc="['默认列举所有通知公告']">
|
||||
|
||||
| 通知公告 | 工作信息 | 招生信息 | 培养信息 | 学位学科 | 国际交流 | 创新工程 |
|
||||
| -------- | -------- | -------- | -------- | -------- | -------- | -------- |
|
||||
| 空 | gzxx | xwxx1 | pyxx | xwxx | gjjl | cxgc |
|
||||
|
||||
</Route>
|
||||
|
||||
### 电子信息与电气工程学院学生工作办公室
|
||||
|
||||
<Route author="Polynomia xxchan" example="/sjtu/seiee/xsb/news" path="/sjtu/seiee/xsb/:type?" :paramsDesc="['默认列举所有通知公告']">
|
||||
<Route author="Polynomia xxchan" example="/sjtu/seiee/xsb/news" path="/sjtu/seiee/xsb/:type?" :paramsDesc="['默认列举所有通知公告']" radar="1">
|
||||
|
||||
| 信息通告 | 奖学金 | 助学金 | 讲座活动 | 党团活动 | 新闻发布 | 本科生综合测评 |
|
||||
| -------- | ----------- | ------------ | -------- | -------- | -------- | -------------- |
|
||||
|
|
@ -2608,9 +2598,31 @@ jsjxy.hbut.edu.cn 证书链不全,自建 RSSHub 可设置环境变量 NODE_TLS
|
|||
|
||||
</Route>
|
||||
|
||||
### 研究生通知公告
|
||||
|
||||
<Route author="mzr1996 dzx-dzx" example="/sjtu/gs/enroll/59" path="/sjtu/gs/:type/:num?" :paramsDesc="['类别', '细分类别, 仅对`type`为`enroll`或`exchange`有效']" radar="1">
|
||||
|
||||
| 工作信息 | 招生信息 | 培养信息 | 学位学科 | 国际交流 | 创新工程 |
|
||||
| -------- | -------- | -------- | -------- | -------- | -------- |
|
||||
| work | enroll | train | degree | exchange | xsjy |
|
||||
|
||||
当`type`为`enroll`, `num`可选字段:
|
||||
|
||||
| 58 | 59 | 60 | 61 | 62 |
|
||||
| -------- | -------- | ---------- | -------- | -------- |
|
||||
| 博士招生 | 硕士招生 | 港澳台招生 | 考点信息 | 院系动态 |
|
||||
|
||||
当`type`为`exchange`, `num`可选字段:
|
||||
|
||||
| 67 | 68 | 69 | 70 | 71 |
|
||||
| -------------- | -------------- | -------------- | -------------- | -------------- |
|
||||
| 国家公派研究生 | 国际化培养资助 | 校际交换与联培 | 交流与合作项目 | 项目招募与宣讲 |
|
||||
|
||||
</Route>
|
||||
|
||||
### 教务处通知公告
|
||||
|
||||
<Route author="SeanChao" example="/sjtu/jwc/" path="/sjtu/jwc/:type?" :paramsDesc="['默认为 all ']">
|
||||
<Route author="SeanChao" example="/sjtu/jwc" path="/sjtu/jwc/:type?" :paramsDesc="['默认为 notice']" radar="1">
|
||||
|
||||
| 新闻中心 | 通知通告 | 教学运行 | 注册学务 | 研究办 | 教改办 | 综合办 | 语言文字 | 工会与支部 | 通识教育 |
|
||||
| -------- | -------- | --------- | -------- | ------ | ------ | ------ | -------- | ---------- | -------- |
|
||||
|
|
@ -2630,7 +2642,7 @@ jsjxy.hbut.edu.cn 证书链不全,自建 RSSHub 可设置环境变量 NODE_TLS
|
|||
|
||||
### 研究生招生网招考信息
|
||||
|
||||
<Route author="richardchien" example="/sjtu/yzb/zkxx/sszs" path="/sjtu/yzb/zkxx/:type" :paramsDesc="['无默认选项']">
|
||||
<Route author="stdrc" example="/sjtu/yzb/zkxx/sszs" path="/sjtu/yzb/zkxx/:type" :paramsDesc="['无默认选项']" radar="1">
|
||||
|
||||
| 博士招生 | 硕士招生 | 港澳台招生 | 考点信息 | 院系动态 |
|
||||
| -------- | -------- | ---------- | -------- | -------- |
|
||||
|
|
|
|||
|
|
@ -541,14 +541,14 @@ router.get('/shanghaitech/activity', lazyloadRouteHandler('./routes/universities
|
|||
router.get('/shanghaitech/sist/activity', lazyloadRouteHandler('./routes/universities/shanghaitech/sist/activity'));
|
||||
|
||||
// 上海交通大学
|
||||
router.get('/sjtu/seiee/academic', lazyloadRouteHandler('./routes/universities/sjtu/seiee/academic'));
|
||||
router.get('/sjtu/seiee/bjwb/:type', lazyloadRouteHandler('./routes/universities/sjtu/seiee/bjwb'));
|
||||
router.get('/sjtu/seiee/xsb/:type?', lazyloadRouteHandler('./routes/universities/sjtu/seiee/xsb'));
|
||||
// router.get('/sjtu/seiee/academic', lazyloadRouteHandler('./routes/universities/sjtu/seiee/academic'));
|
||||
// router.get('/sjtu/seiee/bjwb/:type', lazyloadRouteHandler('./routes/universities/sjtu/seiee/bjwb'));
|
||||
// router.get('/sjtu/seiee/xsb/:type?', lazyloadRouteHandler('./routes/universities/sjtu/seiee/xsb'));
|
||||
|
||||
router.get('/sjtu/gs/tzgg/:type?', lazyloadRouteHandler('./routes/universities/sjtu/gs/tzgg'));
|
||||
router.get('/sjtu/jwc/:type?', lazyloadRouteHandler('./routes/universities/sjtu/jwc'));
|
||||
router.get('/sjtu/tongqu/:type?', lazyloadRouteHandler('./routes/universities/sjtu/tongqu/activity'));
|
||||
router.get('/sjtu/yzb/zkxx/:type', lazyloadRouteHandler('./routes/universities/sjtu/yzb/zkxx'));
|
||||
// router.get('/sjtu/gs/tzgg/:type?', lazyloadRouteHandler('./routes/universities/sjtu/gs/tzgg'));
|
||||
// router.get('/sjtu/jwc/:type?', lazyloadRouteHandler('./routes/universities/sjtu/jwc'));
|
||||
// router.get('/sjtu/tongqu/:type?', lazyloadRouteHandler('./routes/universities/sjtu/tongqu/activity'));
|
||||
// router.get('/sjtu/yzb/zkxx/:type', lazyloadRouteHandler('./routes/universities/sjtu/yzb/zkxx'));
|
||||
|
||||
// 江南大学
|
||||
router.get('/ju/jwc/:type?', lazyloadRouteHandler('./routes/universities/ju/jwc'));
|
||||
|
|
|
|||
|
|
@ -1,31 +0,0 @@
|
|||
const got = require('@/utils/got');
|
||||
const cheerio = require('cheerio');
|
||||
const util = require('./utils');
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const type = ctx.params.type;
|
||||
let url = '';
|
||||
if (type) {
|
||||
url = `http://www.gs.sjtu.edu.cn/index/tzgg/${type}.htm`;
|
||||
} else {
|
||||
url = 'http://www.gs.sjtu.edu.cn/index/tzgg.htm';
|
||||
}
|
||||
|
||||
const response = await got({
|
||||
method: 'get',
|
||||
url,
|
||||
});
|
||||
|
||||
const data = response.data;
|
||||
|
||||
const $ = cheerio.load(data);
|
||||
const list = $('.comm li').slice(0, 10).get();
|
||||
|
||||
const result = await util.ProcessFeed(list, ctx.cache, url);
|
||||
|
||||
ctx.state.data = {
|
||||
title: $('title').text(),
|
||||
link: url,
|
||||
item: result,
|
||||
};
|
||||
};
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
const got = require('@/utils/got');
|
||||
const cheerio = require('cheerio');
|
||||
const url = require('url');
|
||||
|
||||
const ProcessFeed = async (list, caches, host) => {
|
||||
const requestList = [];
|
||||
|
||||
const result = await Promise.all(
|
||||
list.map(async (item) => {
|
||||
const $ = cheerio.load(item);
|
||||
|
||||
const itemUrl = url.resolve(host, $('a').attr('href'));
|
||||
|
||||
const cache = await caches.get(itemUrl);
|
||||
if (cache) {
|
||||
return Promise.resolve(JSON.parse(cache));
|
||||
}
|
||||
const single = {
|
||||
title: $('a span').text(),
|
||||
link: itemUrl,
|
||||
guid: itemUrl,
|
||||
};
|
||||
|
||||
const es = got.get(itemUrl);
|
||||
requestList.push(es);
|
||||
return Promise.resolve(single);
|
||||
})
|
||||
);
|
||||
|
||||
const responses = await got.all(requestList);
|
||||
|
||||
for (let i = 0; i < responses.length; i++) {
|
||||
const $ = cheerio.load(responses[i].data);
|
||||
|
||||
$('.ssdd a').each(function () {
|
||||
if ($(this).attr('href')) {
|
||||
$(this).attr('href', url.resolve(host, $(this).attr('href')));
|
||||
}
|
||||
});
|
||||
$('.ssdd img').each(function () {
|
||||
if ($(this).attr('src')) {
|
||||
$(this).attr('src', url.resolve(host, $(this).attr('src')));
|
||||
}
|
||||
});
|
||||
result[i].description = $('.ssdd').html();
|
||||
|
||||
const date = new Date(
|
||||
$('.zz span:nth-child(2)')
|
||||
.text()
|
||||
.match(/\d{4}-\d{2}-\d{2}/)
|
||||
);
|
||||
|
||||
const timeZone = 8;
|
||||
const serverOffset = date.getTimezoneOffset() / 60;
|
||||
result[i].pubDate = new Date(date.getTime() - 60 * 60 * 1000 * (timeZone + serverOffset)).toUTCString();
|
||||
caches.set(result[i].link, JSON.stringify(result[i]));
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
ProcessFeed,
|
||||
};
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
const got = require('@/utils/got');
|
||||
const cheerio = require('cheerio');
|
||||
const url = require('url');
|
||||
|
||||
const host = 'http://bjwb.seiee.sjtu.edu.cn';
|
||||
|
||||
module.exports = function (meta, extract) {
|
||||
return async (ctx) => {
|
||||
const { title, local, author } = meta(ctx);
|
||||
|
||||
const link = url.resolve(host, local);
|
||||
const response = await got.get(link);
|
||||
|
||||
const list = extract(cheerio.load(response.data));
|
||||
|
||||
const out = await Promise.all(
|
||||
list.map(async (item) => {
|
||||
const itemUrl = url.resolve(host, 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,
|
||||
author,
|
||||
description: $('.article_content').text(),
|
||||
pubDate: new Date(item.date).toUTCString(),
|
||||
};
|
||||
ctx.cache.set(itemUrl, JSON.stringify(single));
|
||||
return Promise.resolve(single);
|
||||
})
|
||||
);
|
||||
|
||||
ctx.state.data = {
|
||||
title,
|
||||
link,
|
||||
item: out,
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
const got = require('@/utils/got');
|
||||
const cheerio = require('cheerio');
|
||||
const { parseDate } = require('@/utils/parse-date');
|
||||
const timezone = require('@/utils/timezone');
|
||||
const { fetchArticle } = require('@/utils/wechat-mp');
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const type = ctx.params.type;
|
||||
const num = ctx.params.num ?? '';
|
||||
|
||||
const rootUrl = 'https://www.gs.sjtu.edu.cn';
|
||||
const currentUrl = `${rootUrl}/announcement/${type}/${num}`;
|
||||
const response = await got({
|
||||
method: 'get',
|
||||
url: currentUrl,
|
||||
});
|
||||
|
||||
const $ = cheerio.load(response.data);
|
||||
|
||||
const list = $('a.announcement-item')
|
||||
.map((_, item) => {
|
||||
item = $(item);
|
||||
|
||||
const day = item.find('.day').text().trim().replace('.', '-');
|
||||
const year = item.find('.month').text().trim();
|
||||
|
||||
return {
|
||||
title: item.find('.title').text().trim(),
|
||||
link: `${item.attr('href').startsWith('http') ? '' : rootUrl}${item.attr('href')}`,
|
||||
pubDate: timezone(parseDate(`${year}-${day}`, 'YYYY-MM-DD'), +8),
|
||||
};
|
||||
})
|
||||
.get();
|
||||
|
||||
const items = await Promise.all(
|
||||
list.map((item) =>
|
||||
ctx.cache.tryGet(item.link, async () => {
|
||||
|
||||
if (new URL(item.link).hostname === 'mp.weixin.qq.com') {
|
||||
item.description = (await fetchArticle(ctx, item.link)).description;
|
||||
}
|
||||
else {
|
||||
const detailResponse = await got({
|
||||
method: 'get',
|
||||
url: item.link,
|
||||
});
|
||||
const content = cheerio.load(detailResponse.data);
|
||||
|
||||
item.description = content('.page-content').html();
|
||||
}
|
||||
|
||||
return item;
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
ctx.state.data = {
|
||||
title: `${num === '' ? '' : `${$('.category-nav-block .active').text().trim()} - `}${$('div.inner-banner-text .title').text().trim()} - ${$('title').text()}`,
|
||||
link: currentUrl,
|
||||
item: items,
|
||||
};
|
||||
};
|
||||
|
|
@ -22,11 +22,11 @@ async function getFullArticle(link) {
|
|||
const absLink = new URL(relativeLink, urlRoot).href;
|
||||
$(e).attr('href', absLink);
|
||||
});
|
||||
return content.html();
|
||||
return content.html() + ($('.Newslist2').length ? $('.Newslist2').html() : '');
|
||||
}
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const type = ctx.params.type ?? 'all';
|
||||
const type = ctx.params.type ?? 'notice';
|
||||
const config = {
|
||||
all: {
|
||||
section: '通知通告',
|
||||
|
|
@ -86,7 +86,8 @@ module.exports = async (ctx) => {
|
|||
const out = await Promise.all(
|
||||
$('body > div.list-box > div.container > div > div.ny_right > div > div.ny_right_con > div > ul')
|
||||
.find('li')
|
||||
.map(async (i, e) => {
|
||||
.toArray()
|
||||
.map((e) => {
|
||||
const info = $(e).find('.wz');
|
||||
const relativeLink = info.find('a').attr('href');
|
||||
const link = new URL(relativeLink, sectionLink).href;
|
||||
|
|
@ -95,16 +96,16 @@ module.exports = async (ctx) => {
|
|||
const day = timeElement.find('h2').text();
|
||||
const yearAndMonth = timeElement.find('p').text();
|
||||
const pubDate = parseDate(`${yearAndMonth}.${day}`, 'YYYY.MM.DD');
|
||||
const description = await ctx.cache.tryGet(link, () => getFullArticle(link));
|
||||
const single = {
|
||||
title,
|
||||
link,
|
||||
pubDate,
|
||||
description,
|
||||
};
|
||||
return Promise.resolve(single);
|
||||
return ctx.cache.tryGet(link, async () => {
|
||||
const description = await getFullArticle(link);
|
||||
return {
|
||||
title,
|
||||
link,
|
||||
pubDate,
|
||||
description,
|
||||
};
|
||||
});
|
||||
})
|
||||
.get()
|
||||
);
|
||||
|
||||
ctx.state.data = {
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
module.exports = {
|
||||
'/gs/:type/:num?': ['dzx-dzx'],
|
||||
'/jwc/:type?': ['SeanChao'],
|
||||
'/seiee/academic': ['HenryQW'],
|
||||
'/seiee/bjwb/:type': ['Polynomia'],
|
||||
'/seiee/xsb/:type?': ['Polynomia', 'xxchan'],
|
||||
'/tongqu/:type?': ['SeanChao'],
|
||||
'/yzb/zkxx/:type': ['stdrc'],
|
||||
};
|
||||
|
|
@ -0,0 +1,126 @@
|
|||
module.exports = {
|
||||
'sjtu.edu.cn': {
|
||||
_name: '上海交通大学',
|
||||
'bjwb.seiee': [
|
||||
{
|
||||
title: '电子信息与电气工程学院',
|
||||
docs: 'https://docs.rsshub.app/university.html#shang-hai-jiao-tong-da-xue',
|
||||
source: ['/seiee/list/:type', '/bkjwb/list/:type', '/xsb/list/:type'],
|
||||
target: (params) => {
|
||||
let type = '';
|
||||
switch (params.type) {
|
||||
// /sjtu/seiee/academic
|
||||
case '683-1-20.htm':
|
||||
type = 'academic';
|
||||
break;
|
||||
// /sjtu/seiee/bjwb/:type
|
||||
case '1503-1-20.htm':
|
||||
type = 'bjwb/academic';
|
||||
break;
|
||||
case '1505-1-20.htm':
|
||||
type = 'bjwb/academic';
|
||||
break;
|
||||
case '1506-1-20.htm':
|
||||
type = 'bjwb/postgraduate';
|
||||
break;
|
||||
case '1507-1-20.htm':
|
||||
type = 'bjwb/abroad';
|
||||
break;
|
||||
case '2281-1-20.htm':
|
||||
type = 'bjwb/international';
|
||||
break;
|
||||
// /sjtu/seiee/xsb/:type?
|
||||
case '2938-1-20.htm':
|
||||
type = 'xsb/news';
|
||||
break;
|
||||
case '611-1-20.htm':
|
||||
type = 'xsb/scholarship';
|
||||
break;
|
||||
case '2676-1-20.htm':
|
||||
type = 'xsb/activity';
|
||||
break;
|
||||
case '1981-1-20.htm':
|
||||
type = 'xsb/lecture';
|
||||
break;
|
||||
case '705-1-20.htm':
|
||||
type = 'xsb/all';
|
||||
break;
|
||||
case '1001-1-20.htm':
|
||||
type = 'xsb/financialAid';
|
||||
break;
|
||||
case '3016-1-20.htm':
|
||||
type = 'xsb/zhcp';
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
return `/sjtu/seiee/${type}`;
|
||||
},
|
||||
},
|
||||
],
|
||||
gs: [
|
||||
{
|
||||
title: '研究生通知公告',
|
||||
docs: 'https://docs.rsshub.app/university.html#shang-hai-jiao-tong-da-xue-yan-jiu-sheng-tong-zhi-gong-gao',
|
||||
source: ['/announcement/:type'],
|
||||
target: '/sjtu/gs/:type',
|
||||
},
|
||||
],
|
||||
jwc: [
|
||||
{
|
||||
title: '教务处通知公告',
|
||||
docs: 'https://docs.rsshub.app/university.html#shang-hai-jiao-tong-da-xue',
|
||||
source: ['/xwtg/:type'],
|
||||
target: (params) => {
|
||||
let type = '';
|
||||
switch (params.type) {
|
||||
case 'xwzx.htm':
|
||||
type = 'news';
|
||||
break;
|
||||
case 'tztg.htm':
|
||||
case '':
|
||||
type = 'notice';
|
||||
break;
|
||||
case 'jxyx.htm':
|
||||
type = 'operation';
|
||||
break;
|
||||
case 'zcxw.htm':
|
||||
type = 'affairs';
|
||||
break;
|
||||
case 'yjb.htm':
|
||||
type = 'yjb';
|
||||
break;
|
||||
case 'jgb.htm':
|
||||
type = 'jgb';
|
||||
break;
|
||||
case 'zhb.htm':
|
||||
type = 'zhb';
|
||||
break;
|
||||
case 'yywz.htm':
|
||||
type = 'language';
|
||||
break;
|
||||
case 'ghyzb.htm':
|
||||
type = 'party';
|
||||
break;
|
||||
case 'tsjy.htm':
|
||||
type = 'ge';
|
||||
break;
|
||||
default:
|
||||
type = 'notice';
|
||||
break;
|
||||
}
|
||||
return `/sjtu/jwc/${type}`;
|
||||
},
|
||||
},
|
||||
],
|
||||
tongqu: [{ title: '同去网最新活动', docs: 'https://docs.rsshub.app/university.html#shang-hai-jiao-tong-da-xue' }],
|
||||
yzb: [
|
||||
{
|
||||
title: '研究生招生网招考信息',
|
||||
docs: 'https://docs.rsshub.app/university.html#shang-hai-jiao-tong-da-xue',
|
||||
source: ['/index/zkxx/:type'],
|
||||
target: (params) => `/sjtu/yzb/zkxx/${params.type.replace('.htm', '')}`,
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
module.exports = function (router) {
|
||||
router.get('/gs/:type/:num?', require('./gs'));
|
||||
router.get('/jwc/:type?', require('./jwc'));
|
||||
router.get('/seiee/academic', require('./seiee/academic'));
|
||||
router.get('/seiee/bjwb/:type', require('./seiee/bjwb'));
|
||||
router.get('/seiee/xsb/:type?', require('./seiee/xsb'));
|
||||
router.get('/tongqu/:type?', require('./tongqu/activity'));
|
||||
router.get('/yzb/zkxx/:type', require('./yzb/zkxx'));
|
||||
};
|
||||
|
|
@ -3,16 +3,15 @@ const workerFactory = require('./utils');
|
|||
module.exports = workerFactory(
|
||||
() => ({
|
||||
title: '上海交通大学电子信息与电气工程学院本科教务办 -- 学术动态',
|
||||
local: `seiee/list/683-1-20.htm`,
|
||||
local: 'seiee/list/683-1-20.htm',
|
||||
author: '上海交通大学电子信息与电气工程学院本科教务办',
|
||||
}),
|
||||
($) =>
|
||||
$('.list_style_1 li')
|
||||
.slice(0, 10)
|
||||
.map((i, e) => ({
|
||||
.toArray()
|
||||
.map((e) => ({
|
||||
date: $(e).children('span').text(),
|
||||
title: $(e).children('a').text(),
|
||||
title: $(e).children('a').attr('title'),
|
||||
link: $(e).children('a').attr('href'),
|
||||
}))
|
||||
.get()
|
||||
);
|
||||
|
|
@ -4,23 +4,23 @@ module.exports = workerFactory(
|
|||
(ctx) => {
|
||||
const config = {
|
||||
abroad: {
|
||||
link: `bkjwb/list/1507-1-20.htm`,
|
||||
link: 'bkjwb/list/1507-1-20.htm',
|
||||
title: '交换交流',
|
||||
},
|
||||
international: {
|
||||
link: `bkjwb/list/2281-1-20.htm`,
|
||||
link: 'bkjwb/list/2281-1-20.htm',
|
||||
title: '国际办学通知',
|
||||
},
|
||||
major_select: {
|
||||
link: `bkjwb/list/1503-1-20.htm`,
|
||||
link: 'bkjwb/list/1503-1-20.htm',
|
||||
title: '分专业',
|
||||
},
|
||||
major_transfer: {
|
||||
link: `bkjwb/list/1505-1-20.htm`,
|
||||
link: 'bkjwb/list/1505-1-20.htm',
|
||||
title: '转专业',
|
||||
},
|
||||
postgraduate: {
|
||||
link: `bkjwb/list/1506-1-20.htm`,
|
||||
link: 'bkjwb/list/1506-1-20.htm',
|
||||
title: '直升研究生',
|
||||
},
|
||||
};
|
||||
|
|
@ -35,11 +35,10 @@ module.exports = workerFactory(
|
|||
},
|
||||
($) =>
|
||||
$('.list_box_5 li')
|
||||
.slice(0, 10)
|
||||
.map((i, e) => ({
|
||||
.toArray()
|
||||
.map((e) => ({
|
||||
date: $(e).children('span').text().slice(1, -1),
|
||||
title: $(e).children('a').text().slice(2),
|
||||
link: $(e).children('a').attr('href'),
|
||||
}))
|
||||
.get()
|
||||
);
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
const got = require('@/utils/got');
|
||||
const cheerio = require('cheerio');
|
||||
const { parseDate } = require('@/utils/parse-date');
|
||||
|
||||
const host = 'https://bjwb.seiee.sjtu.edu.cn';
|
||||
|
||||
module.exports = function (meta, extract) {
|
||||
return async (ctx) => {
|
||||
const { title, local, author } = meta(ctx);
|
||||
|
||||
const link = new URL(local, host).href;
|
||||
const response = await got(link);
|
||||
|
||||
const list = extract(cheerio.load(response.data));
|
||||
|
||||
const out = await Promise.all(
|
||||
list.map((item) => {
|
||||
const itemUrl = new URL(item.link, host).href;
|
||||
return ctx.cache.tryGet(itemUrl, async () => {
|
||||
const response = await got(itemUrl);
|
||||
const $ = cheerio.load(response.data);
|
||||
|
||||
return {
|
||||
title: item.title,
|
||||
link: itemUrl,
|
||||
author,
|
||||
description: $('.article_content').html(),
|
||||
pubDate: parseDate(item.date, 'YYYY-MM-DD'),
|
||||
};
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
ctx.state.data = {
|
||||
title,
|
||||
link,
|
||||
item: out,
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
@ -43,11 +43,10 @@ module.exports = workerFactory(
|
|||
},
|
||||
($) =>
|
||||
$('.list_box_5_2 li')
|
||||
.slice(0, 10)
|
||||
.map((i, e) => ({
|
||||
.toArray()
|
||||
.map((e) => ({
|
||||
date: $(e).children('span').text().slice(1, -1),
|
||||
title: $(e).children('a').text().slice(1),
|
||||
link: $(e).children('a').attr('href'),
|
||||
}))
|
||||
.get()
|
||||
);
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{{ e.name }}<br>
|
||||
开始时间: {{ e.sign_start_time }}<br>
|
||||
结束时间: {{ e.sign_end_time }}<br>
|
||||
地点: {{ e.location }}<br>
|
||||
报名人数: {{ e.member_count }}/{{ e.max_member }}<br>
|
||||
来自{{ e.source }}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
const got = require('@/utils/got');
|
||||
const url = require('url');
|
||||
const { art } = require('@/utils/render');
|
||||
const { join } = require('path');
|
||||
|
||||
const urlRoot = 'https://tongqu.sjtu.edu.cn';
|
||||
|
||||
|
|
@ -30,9 +31,9 @@ module.exports = async (ctx) => {
|
|||
const activities = data.result.acts;
|
||||
const feeds = activities.map((e) => ({
|
||||
title: e.name,
|
||||
link: url.resolve(urlRoot, '/act/' + e.actid),
|
||||
link: new URL(`/act/${e.actid}`, urlRoot).href,
|
||||
category: e.typename,
|
||||
description: `${e.name}\r\n` + `开始时间: ${e.sign_start_time}\r\n结束时间: ${e.sign_end_time}\r\n` + `地点: ${e.location}\r\n` + `报名人数: ${e.member_count}/${e.max_member}\r\n` + `来自${e.source}\r\n`,
|
||||
description: art(join(__dirname, '../templates/activity.art'), { e }),
|
||||
}));
|
||||
|
||||
ctx.state.data = {
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
const got = require('@/utils/got');
|
||||
const cheerio = require('cheerio');
|
||||
const url = require('url');
|
||||
const { parseDate } = require('@/utils/parse-date');
|
||||
|
||||
const baseTitle = '上海交通大学研究生招生网招考信息';
|
||||
const baseUrl = 'https://yzb.sjtu.edu.cn/index/zkxx/';
|
||||
|
|
@ -22,12 +22,11 @@ module.exports = async (ctx) => {
|
|||
link: pageUrl,
|
||||
title: `${baseTitle} -- ${$('title').text().split('-')[0]}`,
|
||||
item: $('li[id^="line"] a')
|
||||
.slice(0, 10)
|
||||
.map((_, elem) => ({
|
||||
link: url.resolve(pageUrl, elem.attribs.href),
|
||||
.toArray()
|
||||
.map((elem) => ({
|
||||
link: new URL(elem.attribs.href, pageUrl).href,
|
||||
title: elem.attribs.title,
|
||||
pubDate: new Date($(elem.next).text().trim()).toUTCString(),
|
||||
}))
|
||||
.get(),
|
||||
pubDate: parseDate($(elem.next).text().trim()),
|
||||
})),
|
||||
};
|
||||
};
|
||||
Loading…
Reference in New Issue