作业基本信息
这个作业属于哪个课程 | 软件工程实践2002年春-F班 |
---|---|
这个作业要求在哪里 | 作业要求 |
这个作业的目标 | 1. 完成课程前期准备 2. 熟悉Java爬虫和命令行控制文件操作 3. 阅读《构建之法》 4. 学习单元测试 |
其他参考文献 | 《构建之法》 |
目录
作业基本信息…
1.Gitcode项目地址
2.PSP表格
PSP | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | ||
• Estimate | • 估计这个任务需要多少时间 | 20 | 20 |
Development | • 开发 | ||
• Analysis | • 需求分析 (包括学习新技术) | 60 | 180 |
• Design Spec | • 生成设计文档 | 30 | 30 |
• Design Review | • 设计复审 | 10 | 12 |
• Coding Standard | • 代码规范 (为目前的开发制定合适的规范) | 20 | 20 |
• Design | • 具体设计 | 20 | 20 |
• Coding | • 具体编码 | 360 | 480 |
• Code Review | • 代码复审 | 10 | 10 |
• Test | • 测试(自我测试,修改代码,提交修改 | 120 | 240 |
Reporting | 报告 | ||
• Test Repor | • 测试报告 | 100 | 120 |
• Size Measurement | • 计算工作量 | 10 | 10 |
• Postmortem & Process Improvement Plan | • 事后总结, 并提出过程改进计划 | 10 | 10 |
合计 | 750 | 1152 |
3.解题思路描述
1. 爬取数据
数据文件一定就在html代码里面,关键就在于获取html然后解析它。发现一个问题,奥运会的网站是动态页面,直接获取的html当中实际上并没有直接的数据,但是打开网页按F12仍然能找到对应的数据标签,这怎么办呢?我发现了一个非常好用的包,叫做htmlunit,利用它就可以把动态的html解析成静态,这时候用html解析器就能成功得到需要的标签了
具体来说,奖牌榜的数据抓获比较简单,因为网站内容只有一页,而每日赛程的URL每一天都不一样,容易发现,当按日期点击赛程查询,URL变成了如http://2022.cctv.com/schedule/date/index.shtml?date=20220219这样的格式,只需要在?date=后加上相应日期,就是每一天的赛程页面的URL了,通过此URL,解析成静态网页,最后同样可以提取到对应数据的标签
2. 数据处理
最方便的当然是json了,爬取的数据先存到对象数组,然后用json解析器给序列化成json数组,存放到data文件夹中。而执行主要操作时,从data文件夹读入json字符串,反序列化到对象数组,操作十分方便。
需要注意,爬取的数据的比赛名,直接显示了比分,而需求是显示成XXvsXX的格式,所以还需要稍加改动name属性
3.核心逻辑部分
逐行处理指令,节省时间。对每一行指令,先去除首位空格,再用空格分隔字符串成字符串数组,这样可以允许用户输入多个空格。对于每一个这样的字符串数组,判断大小是不是1,如果是则只有当此字符串为”total“时才是合法指令;如果是2,则为第一个字符串”schedule“才是合法指令,并且第二个要是规范的日期格式;如果是3,也是非法指令
题目要求最后不能有换行符,所以每条指令输出到文件最后都删一个换行符,注意文件不空时,先补一个换行符在StringBuffer的最前面
4.接口设计和实现过程
Lib:读取并处理操作类
OlympicSearch:主类
Spider:获取数据类
Medal:国家奖牌信息类
Schedule:每日赛程类
Lib作为封装的接口,它是一个静态类,可以被测试类直接调用它有三个方法,分别用于处理赛程、处理奖牌榜、处理总的输出到output文件的操作。爬虫的具体代码实现分别在Medal类和Schedule类中,而Spider类的main方法仅仅调用Medal.getMedalListJson()和Schedule.getSchedual()。实际上,除了属性以外,Medal类和Schedule类只有各自的一个爬取数据的方法。
独到之处在于,爬虫的功能是独立的,随时可以重新爬取,但是当不需要的时候,我们直接读取data文件夹中的txt文件即可
5.关键代码展示
入口部分代码:
获得数据
处理奖牌榜
处理每日赛程
6.性能改进
起初全部读入指令才处理,每次都要new 一个 String出来,比较浪费时间,后来发现应该逐行读入
String类读取大字符串太慢了,查阅资料,改用了StringBuffer
7.单元测试
这里使用了 Junit4进行单元测试分析
没有覆盖的是爬取数据和处理异常的代码
8.异常处理
要处理的异常还是很多的,需要判断Java -jar指令的输入文件是否存在,需要处理文件输入输出的异常,还有文件读写异常
9.心得体会
1. 花费时间确实不好估计,一定要尽早开始,提前规划
2. 看了下其他一些同学的优化,发现原来还有很多可以学习和提高的地方,我不能局限于完成任务,还要把任务完成得优秀才行
3. 文档应该随着代码更进进行同步更新,不然容易有疏漏,很多东西当时想好要写进文档,后来又忘记了