From f0f561a8948983f8d3d7c25f211360aa0781ffc9 Mon Sep 17 00:00:00 2001 From: Aicnal Liueic Date: Fri, 7 Nov 2025 18:28:16 +0800 Subject: [PATCH] feat(router): add router of Capital Normal University (#20430) --- lib/routes/cnu/iec.ts | 71 +++++++++++++++++++++++++++++ lib/routes/cnu/jdxw.ts | 59 ++++++++++++++++++++++++ lib/routes/cnu/jwc.ts | 66 +++++++++++++++++++++++++++ lib/routes/cnu/namespace.ts | 7 +++ lib/routes/cnu/physics.ts | 89 +++++++++++++++++++++++++++++++++++++ lib/routes/cnu/smkxxy.ts | 58 ++++++++++++++++++++++++ 6 files changed, 350 insertions(+) create mode 100644 lib/routes/cnu/iec.ts create mode 100644 lib/routes/cnu/jdxw.ts create mode 100644 lib/routes/cnu/jwc.ts create mode 100644 lib/routes/cnu/namespace.ts create mode 100644 lib/routes/cnu/physics.ts create mode 100644 lib/routes/cnu/smkxxy.ts diff --git a/lib/routes/cnu/iec.ts b/lib/routes/cnu/iec.ts new file mode 100644 index 0000000000..cc584863fc --- /dev/null +++ b/lib/routes/cnu/iec.ts @@ -0,0 +1,71 @@ +import got from '@/utils/got'; +import { load } from 'cheerio'; +import { parseDate } from '@/utils/parse-date'; +import { Route } from '@/types'; + +export const route: Route = { + path: '/iec', + categories: ['university'], + example: '/cnu/iec', + parameters: {}, + radar: [ + { + source: ['iec.cnu.edu.cn/ggml/tzgg1/index.htm'], + target: '/cnu/iec', + }, + ], + name: '信息工程学院通知公告', + maintainers: ['liueic'], + handler, + url: 'iec.cnu.edu.cn/ggml/tzgg1/index.htm', + features: { + requireConfig: false, + requirePuppeteer: false, + antiCrawler: false, + supportBT: false, + supportPodcast: false, + supportScihub: false, + }, +}; + +async function handler() { + const baseUrl = 'https://iec.cnu.edu.cn'; + const link = `${baseUrl}/ggml/tzgg1/index.htm`; + const response = await got(link); + const $ = load(response.data); + + const list = $('.articleList.articleList2 ul > li') + .toArray() + .map((e) => { + const item = $(e); + const span = item.find('span'); + const a = item.find('a'); + + // 提取日期 [YYYY-MM-DD] + const dateText = span.text().trim(); + const dateMatch = dateText.match(/\[(\d{4}-\d{2}-\d{2})\]/); + const pubDate = dateMatch ? parseDate(dateMatch[1], 'YYYY-MM-DD') : undefined; + + // 提取标题 + const title = a.text().trim(); + + // 提取链接 + const href = a.attr('href'); + const linkUrl = href?.startsWith('http') ? href : `${baseUrl}/ggml/tzgg1/${href}`; + + return { + title, + link: linkUrl, + pubDate, + description: '', + }; + }) + .filter((item) => item.title && item.link); // 过滤掉无效项 + + return { + title: '首都师范大学信息工程学院 - 通知公告', + link, + description: '首都师范大学信息工程学院通知公告', + item: list, + }; +} diff --git a/lib/routes/cnu/jdxw.ts b/lib/routes/cnu/jdxw.ts new file mode 100644 index 0000000000..2179592e2e --- /dev/null +++ b/lib/routes/cnu/jdxw.ts @@ -0,0 +1,59 @@ +import got from '@/utils/got'; +import { load } from 'cheerio'; +import { parseDate } from '@/utils/parse-date'; +import { Route } from '@/types'; + +export const route: Route = { + path: '/jdxw', + categories: ['university'], + example: '/cnu/jdxw', + parameters: {}, + radar: [ + { + source: ['news.cnu.edu.cn/xysx/jdxw/index.htm'], + target: '/cnu/jdxw', + }, + ], + name: '焦点关注', + maintainers: ['liueic'], + handler, + url: 'news.cnu.edu.cn/xysx/jdxw/index.htm', + features: { + requireConfig: false, + requirePuppeteer: false, + antiCrawler: false, + supportBT: false, + supportPodcast: false, + supportScihub: false, + }, +}; + +async function handler() { + const baseUrl = 'https://news.cnu.edu.cn'; + const link = `${baseUrl}/xysx/jdxw/index.htm`; + const response = await got(link); + const $ = load(response.data); + + const list = $('ul.list3 > li') + .toArray() + .map((e) => { + const item = $(e); + const a = item.find('a'); + const href = a.attr('href'); + const linkUrl = href?.startsWith('http') ? href : `${baseUrl}/xysx/jdxw/${href}`; + + return { + title: item.find('span.listTitle').text().trim(), + link: linkUrl, + pubDate: parseDate(item.find('span.listDate').text().trim(), 'YYYY-MM-DD'), + description: '', + }; + }); + + return { + title: '首都师范大学新闻网 - 焦点关注', + link, + description: '首都师范大学新闻网焦点关注栏目最新新闻', + item: list, + }; +} diff --git a/lib/routes/cnu/jwc.ts b/lib/routes/cnu/jwc.ts new file mode 100644 index 0000000000..99fa0f5a9b --- /dev/null +++ b/lib/routes/cnu/jwc.ts @@ -0,0 +1,66 @@ +import got from '@/utils/got'; +import { load } from 'cheerio'; +import { parseDate } from '@/utils/parse-date'; +import { Route } from '@/types'; + +export const route: Route = { + path: '/jwc', + categories: ['university'], + example: '/cnu/jwc', + parameters: {}, + radar: [ + { + source: ['jwc.cnu.edu.cn/tzgg/index.htm'], + target: '/cnu/jwc', + }, + ], + name: '教务处通知公示', + maintainers: ['liueic'], + handler, + url: 'jwc.cnu.edu.cn/tzgg/index.htm', + features: { + requireConfig: false, + requirePuppeteer: false, + antiCrawler: false, + supportBT: false, + supportPodcast: false, + supportScihub: false, + }, +}; + +async function handler() { + const baseUrl = 'https://jwc.cnu.edu.cn'; + const link = `${baseUrl}/tzgg/index.htm`; + const response = await got(link); + const $ = load(response.data); + + const list = $('li > a') + .has('span.title') + .toArray() + .map((e) => { + const item = $(e); + const href = item.attr('href'); + const linkUrl = href?.startsWith('http') ? href : `${baseUrl}/tzgg/${href}`; + + const dateSpan = item.find('span.date'); + const day = dateSpan.find('span.day').text().trim(); + const year = dateSpan.find('span.year').text().trim(); + const pubDate = year && day ? parseDate(`${year}-${day}`, 'YYYY-MM-DD') : null; + + const categoryName = item.find('span.name').text().trim(); + return { + title: item.find('span.title').text().trim(), + link: linkUrl, + pubDate: pubDate || undefined, + category: categoryName ? [categoryName] : undefined, + description: '', + }; + }); + + return { + title: '首都师范大学教务处 - 通知公示', + link, + description: '首都师范大学教务处通知公示', + item: list, + }; +} diff --git a/lib/routes/cnu/namespace.ts b/lib/routes/cnu/namespace.ts new file mode 100644 index 0000000000..3beaa9cadd --- /dev/null +++ b/lib/routes/cnu/namespace.ts @@ -0,0 +1,7 @@ +import type { Namespace } from '@/types'; + +export const namespace: Namespace = { + name: '首都师范大学', + url: 'cnu.edu.cn', + lang: 'zh-CN', +}; diff --git a/lib/routes/cnu/physics.ts b/lib/routes/cnu/physics.ts new file mode 100644 index 0000000000..48b5519e57 --- /dev/null +++ b/lib/routes/cnu/physics.ts @@ -0,0 +1,89 @@ +import got from '@/utils/got'; +import { load } from 'cheerio'; +import { parseDate } from '@/utils/parse-date'; +import { Route } from '@/types'; + +export const route: Route = { + path: '/physics', + categories: ['university'], + example: '/cnu/physics', + parameters: {}, + radar: [ + { + source: ['physics.cnu.edu.cn/news/index.htm'], + target: '/cnu/physics', + }, + ], + name: '物理系院系新闻', + maintainers: ['liueic'], + handler, + url: 'physics.cnu.edu.cn/news/index.htm', + features: { + requireConfig: false, + requirePuppeteer: false, + antiCrawler: false, + supportBT: false, + supportPodcast: false, + supportScihub: false, + }, +}; + +async function handler() { + const baseUrl = 'https://physics.cnu.edu.cn'; + const link = `${baseUrl}/news/index.htm`; + const response = await got(link); + const $ = load(response.data); + + const list = $('.list ul > li') + .has('span') + .toArray() + .map((e) => { + const item = $(e); + const span = item.find('span'); + const a = item.find('a'); + + // 提取日期 [YYYY-MM-DD] + const dateText = span.text().trim(); + const dateMatch = dateText.match(/\[(\d{4}-\d{2}-\d{2})\]/); + const pubDate = dateMatch ? parseDate(dateMatch[1], 'YYYY-MM-DD') : undefined; + + // 提取标题 + const title = a.text().trim() || a.attr('title') || ''; + + // 从 onclick 属性中提取链接 + const onclick = a.attr('onclick') || ''; + const hrefMatch = onclick.match(/checkXnwk\(['"]([^'"]+)['"]/); + const href = hrefMatch ? hrefMatch[1] : ''; + + // 处理相对路径 + let linkUrl = ''; + if (href) { + if (href.startsWith('http')) { + linkUrl = href; + } else { + // 使用 URL 构造函数处理所有类型的相对路径(包括 '../' 和 '../..' 等) + try { + linkUrl = new URL(href, `${baseUrl}/news/`).href; + } catch { + // 如果 URL 构造失败,回退到简单拼接 + linkUrl = href.startsWith('../') ? `${baseUrl}/${href.replaceAll('../', '')}` : `${baseUrl}/news/${href}`; + } + } + } + + return { + title, + link: linkUrl, + pubDate, + description: '', + }; + }) + .filter((item) => item.title && item.link); // 过滤掉导航链接 + + return { + title: '首都师范大学物理系 - 院系新闻', + link, + description: '首都师范大学物理系院系新闻', + item: list, + }; +} diff --git a/lib/routes/cnu/smkxxy.ts b/lib/routes/cnu/smkxxy.ts new file mode 100644 index 0000000000..afbfe7d7bb --- /dev/null +++ b/lib/routes/cnu/smkxxy.ts @@ -0,0 +1,58 @@ +import got from '@/utils/got'; +import { load } from 'cheerio'; +import { parseDate } from '@/utils/parse-date'; +import { Route } from '@/types'; + +export const route: Route = { + path: '/smkxxy', + categories: ['university'], + example: '/cnu/smkxxy', + parameters: {}, + radar: [ + { + source: ['smkxxy.cnu.edu.cn/tzgg3/index.htm'], + target: '/cnu/smkxxy', + }, + ], + name: '生命科学学院通知公告', + maintainers: ['liueic'], + handler, + url: 'smkxxy.cnu.edu.cn/tzgg3/index.htm', + features: { + requireConfig: false, + requirePuppeteer: false, + antiCrawler: false, + supportBT: false, + supportPodcast: false, + supportScihub: false, + }, +}; + +async function handler() { + const baseUrl = 'https://smkxxy.cnu.edu.cn'; + const link = `${baseUrl}/tzgg3/index.htm`; + const response = await got(link); + const $ = load(response.data); + + const list = $('ul.block-list > li > a') + .toArray() + .map((e) => { + const item = $(e); + const href = item.attr('href'); + const linkUrl = href?.startsWith('http') ? href : `${baseUrl}/tzgg3/${href}`; + + return { + title: item.find('p.gpArticleTitle').text().trim(), + link: linkUrl, + pubDate: parseDate(item.find('span.gpArticleDate').text().trim(), 'YYYY-MM-DD'), + description: '', + }; + }); + + return { + title: '首都师范大学生命科学学院 - 通知公告', + link, + description: '首都师范大学生命科学学院通知公告', + item: list, + }; +}