From d454ef8f4733f60275eaebf56360cdcbd6ff4f7d Mon Sep 17 00:00:00 2001
From: powerfullz <61956140+powerfullz@users.noreply.github.com>
Date: Thu, 23 Jul 2026 22:17:31 +0800
Subject: [PATCH] fix(route/csust): various fixes and improvements (#22704)
* fix(route/csust): self-contained routes, full title extraction, absolute URLs
- Remove factory pattern from utils.ts, keep only getNoticeContent helper
- Each route (tggs/xkxs) now self-contained with inline list parsing
- Extract full title from article page
tag to avoid truncation
- Convert relative URLs to absolute in article content
* fix(route/csust): remove redundant logics
---
lib/routes/csust/tggs.ts | 51 ++++++++++++++++------
lib/routes/csust/utils.ts | 90 +++++++--------------------------------
lib/routes/csust/xkxs.ts | 51 ++++++++++++++++------
3 files changed, 89 insertions(+), 103 deletions(-)
diff --git a/lib/routes/csust/tggs.ts b/lib/routes/csust/tggs.ts
index 38d44b98a..6da0a2579 100644
--- a/lib/routes/csust/tggs.ts
+++ b/lib/routes/csust/tggs.ts
@@ -1,25 +1,48 @@
-import type { Route } from '@/types';
+import { load } from 'cheerio';
-import { createCsustHandler } from './utils';
+import type { Data, DataItem, Route } from '@/types';
+import cache from '@/utils/cache';
+import got from '@/utils/got';
+import { parseDate } from '@/utils/parse-date';
+import timezone from '@/utils/timezone';
-const handler = createCsustHandler({
- listPath: '/tggs.htm',
- feedTitle: '长沙理工大学 - 通告公示',
- feedDescription: '长沙理工大学通告公示',
-});
+import { getNoticeContent } from './utils';
+
+const baseUrl = 'https://www.csust.edu.cn';
+const listPath = '/tggs.htm';
+
+async function handler(): Promise {
+ const response = await got(`${baseUrl}${listPath}`);
+ const $ = load(response.body);
+
+ const items: Array = $('.list ul li')
+ .toArray()
+ .map((li) => {
+ const $li = $(li);
+
+ return {
+ title: $li.find('.newTitle').text().trim(),
+ link: new URL($li.find('a').attr('href')!, baseUrl).href,
+ pubDate: timezone(parseDate($li.find('.data1').text().trim(), '发布时间 : YYYY-MM-DD'), 8),
+ };
+ });
+
+ const enrichedItems = await Promise.all(items.map((item) => cache.tryGet(item.link, () => getNoticeContent(item))));
+
+ return {
+ title: '长沙理工大学 - 通告公示',
+ link: `${baseUrl}${listPath}`,
+ description: '长沙理工大学通告公示',
+ item: enrichedItems,
+ };
+}
export const route: Route = {
path: '/tggs',
categories: ['university'],
example: '/csust/tggs',
- parameters: {},
features: {
- requireConfig: false,
- requirePuppeteer: false,
- antiCrawler: false,
- supportBT: false,
- supportPodcast: false,
- supportScihub: false,
+ supportRadar: true,
},
radar: [
{
diff --git a/lib/routes/csust/utils.ts b/lib/routes/csust/utils.ts
index 5e69f612d..ef9638ac1 100644
--- a/lib/routes/csust/utils.ts
+++ b/lib/routes/csust/utils.ts
@@ -1,86 +1,26 @@
-import type { CheerioAPI } from 'cheerio';
import { load } from 'cheerio';
-import cache from '@/utils/cache';
+import type { DataItem } from '@/types';
import got from '@/utils/got';
-import { parseDate } from '@/utils/parse-date';
-// 抓取并清清理内容
-export async function getNoticeContent(item: any) {
+type NoticeItem = DataItem & { link: string };
+
+export async function getNoticeContent(item: NoticeItem): Promise {
const response = await got(item.link);
const $ = load(response.body);
+ const pageTitle = $('title').text();
const $content = $('.v_news_content');
+ $content.find('script, style, .vsbcontent_end').remove();
+ $content.find('img[src], a[href]').each((_, element) => {
+ const $element = $(element);
+ const attribute = element.tagName === 'img' ? 'src' : 'href';
+ $element.attr(attribute, new URL($element.attr(attribute)!, item.link).href);
+ });
- if ($content.length) {
- // 移除无用元素
- $content.find('script').remove();
- $content.find('style').remove();
- $content.find('.vsbcontent_end').remove();
- $content.find('iframe').remove();
- item.description = $content.html() || item.title;
- } else {
- item.description = item.title;
- }
-
- return item;
-}
-
-// 解析列表页面,返回包含标题、链接与发布日期的条目
-export function parseListItems($: CheerioAPI, baseUrl: string) {
- return $('.list ul li')
- .toArray()
- .map((li) => {
- const element = $(li);
- const title = element.find('.newTitle').text().trim();
- const linkRaw = element.find('a').attr('href');
- const dateText = element.find('.data1').text().trim();
-
- if (!linkRaw || !title) {
- return null;
- }
-
- const dateMatch = dateText.match(/发布时间\s*[::]\s*(\d{4}-\d{1,2}-\d{1,2})/);
- const pubDate = dateMatch ? parseDate(dateMatch[1]) : null;
-
- // 使用 URL 构造函数确保正确拼接 URL
- const link = linkRaw.startsWith('http') ? linkRaw : new URL(linkRaw, baseUrl).href;
-
- return {
- title,
- link,
- pubDate,
- } as any;
- })
- .filter((i) => i !== null) as any[];
-}
-
-// 通用处理器工厂:根据栏目路径与标题信息生成 handler
-export function createCsustHandler({ listPath, feedTitle, feedDescription }: { listPath: string; feedTitle: string; feedDescription: string }) {
- const baseUrl = 'https://www.csust.edu.cn';
- return async function () {
- const response = await got(`${baseUrl}${listPath}`);
- const $ = load(response.body);
-
- const items = parseListItems($, baseUrl);
-
- const item = await Promise.all(
- items.map((it) =>
- cache.tryGet(it.link, async () => {
- try {
- return await getNoticeContent(it);
- } catch {
- return it;
- }
- })
- )
- );
-
- return {
- title: feedTitle,
- link: `${baseUrl}${listPath}`,
- description: feedDescription,
- item,
- };
+ return {
+ ...item,
+ title: pageTitle.slice(0, pageTitle.lastIndexOf('-')).trim(),
+ description: $content.html()!,
};
}
diff --git a/lib/routes/csust/xkxs.ts b/lib/routes/csust/xkxs.ts
index fa641b293..2149799f5 100644
--- a/lib/routes/csust/xkxs.ts
+++ b/lib/routes/csust/xkxs.ts
@@ -1,25 +1,48 @@
-import type { Route } from '@/types';
+import { load } from 'cheerio';
-import { createCsustHandler } from './utils';
+import type { Data, DataItem, Route } from '@/types';
+import cache from '@/utils/cache';
+import got from '@/utils/got';
+import { parseDate } from '@/utils/parse-date';
+import timezone from '@/utils/timezone';
-const handler = createCsustHandler({
- listPath: '/xkxs.htm',
- feedTitle: '长沙理工大学 - 学科学术',
- feedDescription: '长沙理工大学学科学术',
-});
+import { getNoticeContent } from './utils';
+
+const baseUrl = 'https://www.csust.edu.cn';
+const listPath = '/xkxs.htm';
+
+async function handler(): Promise {
+ const response = await got(`${baseUrl}${listPath}`);
+ const $ = load(response.body);
+
+ const items: Array = $('.list ul li')
+ .toArray()
+ .map((li) => {
+ const $li = $(li);
+
+ return {
+ title: $li.find('.newTitle').text().trim(),
+ link: new URL($li.find('a').attr('href')!, baseUrl).href,
+ pubDate: timezone(parseDate($li.find('.data1').text().trim(), '发布时间 : YYYY-MM-DD'), 8),
+ };
+ });
+
+ const enrichedItems = await Promise.all(items.map((item) => cache.tryGet(item.link, () => getNoticeContent(item))));
+
+ return {
+ title: '长沙理工大学 - 学科学术',
+ link: `${baseUrl}${listPath}`,
+ description: '长沙理工大学学科学术',
+ item: enrichedItems,
+ };
+}
export const route: Route = {
path: '/xkxs',
categories: ['university'],
example: '/csust/xkxs',
- parameters: {},
features: {
- requireConfig: false,
- requirePuppeteer: false,
- antiCrawler: false,
- supportBT: false,
- supportPodcast: false,
- supportScihub: false,
+ supportRadar: true,
},
radar: [
{