项目 | 内容 |
---|---|
这个作业属于哪个课程 | 福州大学软件工程实践2022年春-F班 |
这个作业要求在哪里 | 软件工程实践第二次作业——个人实战 |
这个作业的目标 | 爬取数据、实现一个命令行程序 |
其他参考文献 | 优快云 博客园 |
文章目录
1、GitCode项目地址
2、PSP表格
PSP | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | ||
• Estimate | • 估计这个任务需要多少时间 | 695 | 910 |
Development | 开发 | ||
• Analysis | • 需求分析 (包括学习新技术) | 60 | 75 |
• Design Spec | • 生成设计文档 | 30 | 45 |
• Design Review | • 设计复审 | 20 | 25 |
• Coding Standard | • 代码规范 (为目前的开发制定合适的规范) | 15 | 25 |
• Design | • 具体设计 | 60 | 75 |
• Coding | • 具体编码 | 200 | 220 |
• Code Review | • 代码复审 | 30 | 45 |
• Test | • 测试(自我测试,修改代码,提交修改) | 150 | 260 |
Reporting | 报告 | ||
• Test Repor | • 测试报告 | 80 | 100 |
• Size Measurement | • 计算工作量 | 20 | 20 |
• Postmortem & Process Improvement Plan | • 事后总结, 并提出过程改进计划 | 30 | 40 |
合计 | 695 | 910 |
3、解题思路描述
爬取数据
对于爬虫这一概念,仅仅只是听说过名词而已,没有真正实现过。而第一次要实现数据爬取,遇到了不小的麻烦。通过去官网上看js代码、抓包,找到了奖牌数据和赛程数据的接口,发现奖牌的JSON数据较为合理,但是赛程的JSON数据存在许多不需要用到的字段,还有unicode编码,我是真不会操作。所以尝试自己爬取数据(有点笨)。
本次通过Jsoup
来实现爬取数据,但是Jsoup
仅仅只能爬取静态网页的数据,在JS还未加载完成时,就进行数据爬取,存在丢失数据的可能。因此,使用htmlunit(WebClient)
,模拟一个浏览器客户端,设置JS动态加载开启。然后使用HtmlPage
类接受该网页。使用Jsoup
进行清洗数据,操作DOM树,得到我们需要的内容。最后导出文件即可。
但是在提取数据的过程中,出现了一些麻烦,提取出来的有用数据被整合在一整条字符串中,需要进行切片与分类合并。在数据字符串中,每个数据都由空格分开,所以我先把冗余部分移除,再使用split()
方法,分离每段数据,整合进自定义的实体中,然后将实体对象转化成JSON数据。
实现控制台程序
控制台程序的实现思路较为清晰,通过命令行接收输入输出文件路径,读取指令后,从JSON文件中提取出对应数据,将每条指令的结果打印出来即可。
4、接口设计和实现过程
在整个程序的结构中包含以下几种类:
- 实体类:作为JSON数据的载体,供其他类调用。
- 工具类:
- 验证类:包含了整个程序中对各类数据的验证的方法。
- 文件类:包含了data文件夹的路径,以及与文件读取有关的方法。
- 核心类:对外提供接口,需要调用工具类中的方法。
4.1 实体类设计
分别为奖牌榜输出和赛程输出创建实体类Medal
和Schedule
,Medal
类主要包含rank
、countryName
、countryId
、gold
、silver
、bronze
、total
,7个字段;Schedule
类主要包含time
、sport
、name
、venue
、homeName
、awayName
,6个字段。
实体类用于接收JSON文件的数据,同时在toString
方法中,实现作业要求所示的格式。
4.2 工具类设计
4.2.1 文件工具类
为文件的读取创建文件工具类FileUtil
,其中包括以下三种方法:
readFile
:用于普通文件的读取,将文件内容以字符串的形式返回readMedalFile
:用于奖牌榜JSON文件的读取readScheduleFile
:用于赛程JSON文件读取
当data文件夹与其他的类在同一文件夹下时,使用Class.getResourceAsStream
获取资源,路径常量定义如下:
private static final String TOTAL_PATH = "data/total.json";
private static final String SCHEDULE_PATH = "data/schedule/";
4.2.2 验证工具类
为程序运行的过程中所需要的验证创建验证工具类ValidateUtil
,其中包括:
checkArgs
:检查命令行传来的文件参数是否正确isTotal
:检查指令是否属于totalisSchedule
:检查指令是否属于schedulegetValidDate
:获取schedule指令后面的有效日期
4.3 核心类设计
核心类Core
为整个程序对外提供数据的类,其中包括:
result
:根据指令参数,返回对应的数据字符串(对外的主接口)getMedalTotal
:返回奖牌榜数据字符串(供result
使用)getSchedule
:根据日期参数,返回对应日期的赛程字符串(供result
使用)
5、关键代码展示
Core.java
public class Core {
private static final String NA_MESSAGE = "N/A";
private static final String ERROR_MESSAGE = "Error";
private static final String EMPTY_LINE = "";
private static final String TOTAL = "total";
static HashMap<String, String> cacheData = new HashMap<>();
/**
* 输出指令对应的结果
*/
public static String result(String instruction) {
// 判断空行
if (EMPTY_LINE.