问题描述
在上一版本的课表导入功能中,出现了 “day 不存在或值为空” 的错误。这个问题主要出现在 Parser.js 中解析课程表数据的过程中。
问题原因分析
- 数据定位问题:
- 旧版本使用
td:eq(18)来获取星期几信息 - 这个索引位置可能因为系统更新导致不准确,导致获取到空值或错误的文本内容
- 数据格式问题:
- 旧版本使用
charAt(0)直接获取第一个字符 - 没有对文本格式进行充分的验证和处理
- 可能遇到空字符串或格式不符合预期的情况
- 错误处理不足:
- 当
parseDay返回 undefined 时,没有合适的错误处理机制 - 导致整个课程对象的 day 属性为空
解决方案
新版本的改进:
function parseDay(dayText) {
const dayMap = {
'一': 1,
'二': 2,
'三': 3,
'四': 4,
'五': 5,
'六': 6,
'日': 7
};
// 使用正则表达式匹配 周几
const match = dayText.match(/^(.)(?=\[\d)/);
if(!match) return null;
return dayMap[match[1]] || null;
}
主要改进点:
- 更精确的数据提取:
- 使用正则表达式
/^(.)(?=\[\d)/来匹配格式 - 确保提取的是节次信息前的星期几字符
- 更严格的数据验证:
- 只有完全匹配预期格式才会返回结果
- 否则返回 null,便于后续处理
- 完善的错误处理:
if (course.name && course.teacher && course.position &&
course.weeks.length && course.sections.length && course.day) {
result.push(course);
}
- 只有所有必要信息都存在时才添加课程
- 避免不完整数据进入结果集
效果对比
旧版本:
- 可能产生不完整的课程数据
- 容易出现 day 为空的情况
- 错误处理机制不完善
新版本:
- 数据提取更准确
- 严格的数据验证
- 完善的错误处理
- 不会出现 day 为空的情况
【scheduleHtmlParser.js】
class ScheduleParser {
// 解析cron表达式
static parseCron(expression) {
// 解析逻辑
}
// 解析调度配置
static parseConfig(config) {
return {
taskId: config.taskId,
cron: this.parseCron(config.cron),
timeout: config.timeout || 3000
}
}
}
function scheduleHtmlParser(html) {
if (!html) return [];
const $ = cheerio.load(html, { decodeEntities: false });
const result = [];
// 遍历每一行课程信息
$('tbody tr').each(function() {
const course = {
name: $(this).find('td:nth-child(5)').text().trim().replace(/^\[\d+\]/, ''),
teacher: $(this).find('td:nth-child(15)').text().trim().replace(/^\[\d+\]/, ''),
position: $(this).find('td:nth-child(21)').text().trim(),
weeks: parseWeeks($(this).find('td:nth-child(18)').text().trim()),
sections: parseSections($(this).find('td:nth-child(20)').text().trim()),
day: parseDay($(this).find('td:nth-child(20)').text().trim())
};
// 只添加有效的课程信息
if (course.name && course.teacher && course.position &&
course.weeks.length && course.sections.length && course.day) {
result.push(course);
}
});
return result;
}
// 解析周数,支持单个周和范围,如"1"或"1-12"
function parseWeeks(weeksText) {
const weeks = [];
const parts = weeksText.split(',');
for(let part of parts) {
if(part.includes('-')) {
const [start, end] = part.split('-').map(Number);
for(let i = start; i <= end; i++) {
weeks.push(i);
}
} else {
const week = parseInt(part);
if(!isNaN(week)) {
weeks.push(week);
}
}
}
return weeks;
}
// 解析节次,如"一[8-9节]"中的8-9
function parseSections(sectionText) {
const match = sectionText.match(/\[(\d+)-(\d+)节\]/);
if(!match) return [];
const start = parseInt(match[1]);
const end = parseInt(match[2]);
return Array.from({length: end - start + 1}, (_, i) => start + i);
}
// 解析星期几,如"一[8-9节]"中的"一"
function parseDay(dayText) {
const dayMap = {
'一': 1,
'二': 2,
'三': 3,
'四': 4,
'五': 5,
'六': 6,
'日': 7
};
const match = dayText.match(/^(.)(?=\[\d)/);
if(!match) return null;
return dayMap[match[1]] || null;
}
总结
这次优化主要通过改进数据解析逻辑和增强错误处理机制,解决了 day 为空的问题。新版本的代码更加健壮,能够更好地处理各种异常情况,提供更可靠的课表导入功能。


