From ecae7e9799e8d3b55dcba00138216d48e571c5ce Mon Sep 17 00:00:00 2001
From: zhangsiyuan <3837703520@qq.com>
Date: Sat, 30 May 2026 13:33:26 +0800
Subject: [PATCH] =?UTF-8?q?=E6=88=91=E5=B7=B2=E6=8F=90=E4=BA=A4=E4=BA=86?=
=?UTF-8?q?=E6=9C=9F=E6=9C=AB=E5=AE=9E=E9=AA=8C=E6=8A=A5=E5=91=8A?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
project/.idea/.gitignore | 10 +
project/.idea/.name | 1 +
project/.idea/misc.xml | 6 +
project/.idea/modules.xml | 8 +
project/.idea/vcs.xml | 6 +
...2401070104-张思渊-期末实验报告.md | 638 ++++++++++++++++++
...0104-张思渊-期末实验报告docx.docx | Bin 0 -> 788757 bytes
...70104-张思渊-期末实验报告docx.pdf | Bin 0 -> 1182494 bytes
project/bin/Main.class | Bin 0 -> 7287 bytes
.../com/example/datacollect/CrawlTest.class | Bin 0 -> 3764 bytes
.../bin/com/example/datacollect/Main.class | Bin 0 -> 1075 bytes
.../com/example/datacollect/TestHtml.class | Bin 0 -> 2392 bytes
.../datacollect/command/AnalyzeCommand.class | Bin 0 -> 5014 bytes
.../example/datacollect/command/Command.class | Bin 0 -> 329 bytes
.../datacollect/command/CrawlCommand.class | Bin 0 -> 3934 bytes
.../datacollect/command/ExitCommand.class | Bin 0 -> 861 bytes
.../datacollect/command/ExportCommand.class | Bin 0 -> 3013 bytes
.../datacollect/command/HelpCommand.class | Bin 0 -> 1399 bytes
.../datacollect/command/HistoryCommand.class | Bin 0 -> 1874 bytes
.../datacollect/command/ListCommand.class | Bin 0 -> 2042 bytes
.../controller/CrawlerController.class | Bin 0 -> 4510 bytes
.../exception/CrawlerException.class | Bin 0 -> 370 bytes
.../exception/NetworkException.class | Bin 0 -> 401 bytes
.../exception/ParseException.class | Bin 0 -> 397 bytes
.../example/datacollect/model/Article.class | Bin 0 -> 1639 bytes
.../repository/ArticleRepository.class | Bin 0 -> 1098 bytes
.../datacollect/strategy/CrawlStrategy.class | Bin 0 -> 402 bytes
.../strategy/DoubanBookStrategy.class | Bin 0 -> 2617 bytes
.../strategy/DoubanMovieStrategy.class | Bin 0 -> 2833 bytes
.../datacollect/strategy/PoetryStrategy.class | Bin 0 -> 3389 bytes
.../strategy/StrategyFactory.class | Bin 0 -> 2654 bytes
.../datacollect/utils/DataCleaner.class | Bin 0 -> 989 bytes
.../example/datacollect/utils/HttpUtils.class | Bin 0 -> 2502 bytes
.../datacollect/view/ConsoleView.class | Bin 0 -> 1419 bytes
project/bin/project/AutoTest.class | Bin 0 -> 5284 bytes
project/bin/project/Main.class | Bin 0 -> 843 bytes
.../bin/project/analysis/BookAnalyzer.class | Bin 0 -> 5568 bytes
.../bin/project/analysis/JobAnalyzer.class | Bin 0 -> 5391 bytes
.../bin/project/analysis/MovieAnalyzer.class | Bin 0 -> 4570 bytes
.../bin/project/analysis/PoemAnalyzer.class | Bin 0 -> 6279 bytes
project/bin/project/bean/Book.class | Bin 0 -> 2060 bytes
project/bin/project/bean/Job.class | Bin 0 -> 1908 bytes
project/bin/project/bean/Movie.class | Bin 0 -> 1633 bytes
project/bin/project/bean/Poem.class | Bin 0 -> 1587 bytes
project/bin/project/bean/Quote.class | Bin 0 -> 1493 bytes
.../bin/project/command/AnalyzeCommand.class | Bin 0 -> 4220 bytes
project/bin/project/command/Command.class | Bin 0 -> 425 bytes
.../bin/project/command/CrawlCommand.class | Bin 0 -> 3449 bytes
project/bin/project/command/ExitCommand.class | Bin 0 -> 684 bytes
project/bin/project/command/HelpCommand.class | Bin 0 -> 690 bytes
.../bin/project/command/HistoryCommand.class | Bin 0 -> 1188 bytes
project/bin/project/command/ListCommand.class | Bin 0 -> 2936 bytes
project/bin/project/command/SaveCommand.class | Bin 0 -> 2170 bytes
.../controller/CrawlerController.class | Bin 0 -> 4155 bytes
.../bin/project/core/AbstractWebCrawler.class | Bin 0 -> 4811 bytes
project/bin/project/core/DataEntity.class | Bin 0 -> 204 bytes
project/bin/project/core/WebCrawler.class | Bin 0 -> 483 bytes
project/bin/project/crawler/BookCrawler.class | Bin 0 -> 3410 bytes
project/bin/project/crawler/JobCrawler.class | Bin 0 -> 1875 bytes
.../bin/project/crawler/MovieCrawler.class | Bin 0 -> 3705 bytes
project/bin/project/crawler/PoemCrawler.class | Bin 0 -> 2555 bytes
.../bin/project/display/ResultDisplay.class | Bin 0 -> 6142 bytes
.../project/exception/CrawlerException.class | Bin 0 -> 354 bytes
.../project/exception/ParseException.class | Bin 0 -> 365 bytes
.../bin/project/strategy/CrawlStrategy.class | Bin 0 -> 394 bytes
.../bin/project/strategy/CrawlerContext.class | Bin 0 -> 2330 bytes
.../project/strategy/JobCrawlStrategy.class | Bin 0 -> 819 bytes
.../project/strategy/MovieCrawlStrategy.class | Bin 0 -> 833 bytes
.../project/strategy/PoemCrawlStrategy.class | Bin 0 -> 826 bytes
project/bin/project/utils/DataCleaner.class | Bin 0 -> 1961 bytes
project/bin/project/utils/DataStorage.class | Bin 0 -> 4257 bytes
project/bin/project/utils/HttpUtils.class | Bin 0 -> 2561 bytes
project/bin/project/view/ConsoleView.class | Bin 0 -> 9091 bytes
.../visualization/ChartGenerator.class | Bin 0 -> 8515 bytes
project/images/1.png | Bin 0 -> 39639 bytes
project/images/2.png | Bin 0 -> 60306 bytes
project/images/3.png | Bin 0 -> 110755 bytes
project/images/4.png | Bin 0 -> 73836 bytes
project/images/5.png | Bin 0 -> 66575 bytes
project/images/6.png | Bin 0 -> 82350 bytes
project/images/7.png | Bin 0 -> 70534 bytes
project/images/8.png | Bin 0 -> 66890 bytes
.../charts/movie_rating_distribution.png | Bin 0 -> 11430 bytes
project/output/charts/movie_top_directors.png | Bin 0 -> 11203 bytes
project/output/charts/rating_distribution.png | Bin 0 -> 11430 bytes
project/output/charts/rating_range_pie.png | Bin 0 -> 16025 bytes
project/output/charts/top_directors.png | Bin 0 -> 11203 bytes
.../output/charts/year_rating_correlation.png | Bin 0 -> 35475 bytes
project/output/jobs.csv | 21 +
project/output/jobs.json | 162 +++++
project/output/movies.csv | 76 +++
project/output/movies.json | 452 +++++++++++++
project/output/poems.csv | 81 +++
project/output/poems.json | 122 ++++
project/pom.xml | 38 ++
project/project.iml | 11 +
project/src/project/AutoTest.java | 119 ++++
project/src/project/Main.java | 28 +
project/src/project/analysis/JobAnalyzer.java | 76 +++
.../src/project/analysis/PoemAnalyzer.java | 73 ++
project/src/project/bean/Job.java | 52 ++
project/src/project/bean/Poem.java | 43 ++
.../src/project/command/AnalyzeCommand.java | 127 ++++
project/src/project/command/Command.java | 16 +
project/src/project/command/CrawlCommand.java | 115 ++++
project/src/project/command/ExitCommand.java | 27 +
project/src/project/command/HelpCommand.java | 27 +
.../src/project/command/HistoryCommand.java | 41 ++
project/src/project/command/ListCommand.java | 97 +++
project/src/project/command/SaveCommand.java | 71 ++
.../project/controller/CrawlerController.java | 131 ++++
.../src/project/core/AbstractWebCrawler.java | 134 ++++
project/src/project/core/DataEntity.java | 6 +
project/src/project/core/WebCrawler.java | 11 +
project/src/project/crawler/JobCrawler.java | 47 ++
project/src/project/crawler/PoemCrawler.java | 43 ++
.../project/exception/CrawlerException.java | 11 +
.../src/project/exception/ParseException.java | 11 +
.../src/project/strategy/CrawlStrategy.java | 14 +
.../src/project/strategy/CrawlerContext.java | 43 ++
.../project/strategy/JobCrawlStrategy.java | 29 +
.../project/strategy/MovieCrawlStrategy.java | 29 +
.../project/strategy/PoemCrawlStrategy.java | 29 +
project/src/project/view/ConsoleView.java | 213 ++++++
124 files changed, 3295 insertions(+)
create mode 100644 project/.idea/.gitignore
create mode 100644 project/.idea/.name
create mode 100644 project/.idea/misc.xml
create mode 100644 project/.idea/modules.xml
create mode 100644 project/.idea/vcs.xml
create mode 100644 project/202401070104-张思渊-期末实验报告.md
create mode 100644 project/202401070104-张思渊-期末实验报告docx.docx
create mode 100644 project/202401070104-张思渊-期末实验报告docx.pdf
create mode 100644 project/bin/Main.class
create mode 100644 project/bin/com/example/datacollect/CrawlTest.class
create mode 100644 project/bin/com/example/datacollect/Main.class
create mode 100644 project/bin/com/example/datacollect/TestHtml.class
create mode 100644 project/bin/com/example/datacollect/command/AnalyzeCommand.class
create mode 100644 project/bin/com/example/datacollect/command/Command.class
create mode 100644 project/bin/com/example/datacollect/command/CrawlCommand.class
create mode 100644 project/bin/com/example/datacollect/command/ExitCommand.class
create mode 100644 project/bin/com/example/datacollect/command/ExportCommand.class
create mode 100644 project/bin/com/example/datacollect/command/HelpCommand.class
create mode 100644 project/bin/com/example/datacollect/command/HistoryCommand.class
create mode 100644 project/bin/com/example/datacollect/command/ListCommand.class
create mode 100644 project/bin/com/example/datacollect/controller/CrawlerController.class
create mode 100644 project/bin/com/example/datacollect/exception/CrawlerException.class
create mode 100644 project/bin/com/example/datacollect/exception/NetworkException.class
create mode 100644 project/bin/com/example/datacollect/exception/ParseException.class
create mode 100644 project/bin/com/example/datacollect/model/Article.class
create mode 100644 project/bin/com/example/datacollect/repository/ArticleRepository.class
create mode 100644 project/bin/com/example/datacollect/strategy/CrawlStrategy.class
create mode 100644 project/bin/com/example/datacollect/strategy/DoubanBookStrategy.class
create mode 100644 project/bin/com/example/datacollect/strategy/DoubanMovieStrategy.class
create mode 100644 project/bin/com/example/datacollect/strategy/PoetryStrategy.class
create mode 100644 project/bin/com/example/datacollect/strategy/StrategyFactory.class
create mode 100644 project/bin/com/example/datacollect/utils/DataCleaner.class
create mode 100644 project/bin/com/example/datacollect/utils/HttpUtils.class
create mode 100644 project/bin/com/example/datacollect/view/ConsoleView.class
create mode 100644 project/bin/project/AutoTest.class
create mode 100644 project/bin/project/Main.class
create mode 100644 project/bin/project/analysis/BookAnalyzer.class
create mode 100644 project/bin/project/analysis/JobAnalyzer.class
create mode 100644 project/bin/project/analysis/MovieAnalyzer.class
create mode 100644 project/bin/project/analysis/PoemAnalyzer.class
create mode 100644 project/bin/project/bean/Book.class
create mode 100644 project/bin/project/bean/Job.class
create mode 100644 project/bin/project/bean/Movie.class
create mode 100644 project/bin/project/bean/Poem.class
create mode 100644 project/bin/project/bean/Quote.class
create mode 100644 project/bin/project/command/AnalyzeCommand.class
create mode 100644 project/bin/project/command/Command.class
create mode 100644 project/bin/project/command/CrawlCommand.class
create mode 100644 project/bin/project/command/ExitCommand.class
create mode 100644 project/bin/project/command/HelpCommand.class
create mode 100644 project/bin/project/command/HistoryCommand.class
create mode 100644 project/bin/project/command/ListCommand.class
create mode 100644 project/bin/project/command/SaveCommand.class
create mode 100644 project/bin/project/controller/CrawlerController.class
create mode 100644 project/bin/project/core/AbstractWebCrawler.class
create mode 100644 project/bin/project/core/DataEntity.class
create mode 100644 project/bin/project/core/WebCrawler.class
create mode 100644 project/bin/project/crawler/BookCrawler.class
create mode 100644 project/bin/project/crawler/JobCrawler.class
create mode 100644 project/bin/project/crawler/MovieCrawler.class
create mode 100644 project/bin/project/crawler/PoemCrawler.class
create mode 100644 project/bin/project/display/ResultDisplay.class
create mode 100644 project/bin/project/exception/CrawlerException.class
create mode 100644 project/bin/project/exception/ParseException.class
create mode 100644 project/bin/project/strategy/CrawlStrategy.class
create mode 100644 project/bin/project/strategy/CrawlerContext.class
create mode 100644 project/bin/project/strategy/JobCrawlStrategy.class
create mode 100644 project/bin/project/strategy/MovieCrawlStrategy.class
create mode 100644 project/bin/project/strategy/PoemCrawlStrategy.class
create mode 100644 project/bin/project/utils/DataCleaner.class
create mode 100644 project/bin/project/utils/DataStorage.class
create mode 100644 project/bin/project/utils/HttpUtils.class
create mode 100644 project/bin/project/view/ConsoleView.class
create mode 100644 project/bin/project/visualization/ChartGenerator.class
create mode 100644 project/images/1.png
create mode 100644 project/images/2.png
create mode 100644 project/images/3.png
create mode 100644 project/images/4.png
create mode 100644 project/images/5.png
create mode 100644 project/images/6.png
create mode 100644 project/images/7.png
create mode 100644 project/images/8.png
create mode 100644 project/output/charts/movie_rating_distribution.png
create mode 100644 project/output/charts/movie_top_directors.png
create mode 100644 project/output/charts/rating_distribution.png
create mode 100644 project/output/charts/rating_range_pie.png
create mode 100644 project/output/charts/top_directors.png
create mode 100644 project/output/charts/year_rating_correlation.png
create mode 100644 project/output/jobs.csv
create mode 100644 project/output/jobs.json
create mode 100644 project/output/movies.csv
create mode 100644 project/output/movies.json
create mode 100644 project/output/poems.csv
create mode 100644 project/output/poems.json
create mode 100644 project/pom.xml
create mode 100644 project/project.iml
create mode 100644 project/src/project/AutoTest.java
create mode 100644 project/src/project/Main.java
create mode 100644 project/src/project/analysis/JobAnalyzer.java
create mode 100644 project/src/project/analysis/PoemAnalyzer.java
create mode 100644 project/src/project/bean/Job.java
create mode 100644 project/src/project/bean/Poem.java
create mode 100644 project/src/project/command/AnalyzeCommand.java
create mode 100644 project/src/project/command/Command.java
create mode 100644 project/src/project/command/CrawlCommand.java
create mode 100644 project/src/project/command/ExitCommand.java
create mode 100644 project/src/project/command/HelpCommand.java
create mode 100644 project/src/project/command/HistoryCommand.java
create mode 100644 project/src/project/command/ListCommand.java
create mode 100644 project/src/project/command/SaveCommand.java
create mode 100644 project/src/project/controller/CrawlerController.java
create mode 100644 project/src/project/core/AbstractWebCrawler.java
create mode 100644 project/src/project/core/DataEntity.java
create mode 100644 project/src/project/core/WebCrawler.java
create mode 100644 project/src/project/crawler/JobCrawler.java
create mode 100644 project/src/project/crawler/PoemCrawler.java
create mode 100644 project/src/project/exception/CrawlerException.java
create mode 100644 project/src/project/exception/ParseException.java
create mode 100644 project/src/project/strategy/CrawlStrategy.java
create mode 100644 project/src/project/strategy/CrawlerContext.java
create mode 100644 project/src/project/strategy/JobCrawlStrategy.java
create mode 100644 project/src/project/strategy/MovieCrawlStrategy.java
create mode 100644 project/src/project/strategy/PoemCrawlStrategy.java
create mode 100644 project/src/project/view/ConsoleView.java
diff --git a/project/.idea/.gitignore b/project/.idea/.gitignore
new file mode 100644
index 0000000..7d05e99
--- /dev/null
+++ b/project/.idea/.gitignore
@@ -0,0 +1,10 @@
+# 默认忽略的文件
+/shelf/
+/workspace.xml
+# 基于编辑器的 HTTP 客户端请求
+/httpRequests/
+# 依赖于环境的 Maven 主目录路径
+/mavenHomeManager.xml
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/project/.idea/.name b/project/.idea/.name
new file mode 100644
index 0000000..f1d4957
--- /dev/null
+++ b/project/.idea/.name
@@ -0,0 +1 @@
+ConsoleView.java
\ No newline at end of file
diff --git a/project/.idea/misc.xml b/project/.idea/misc.xml
new file mode 100644
index 0000000..0548357
--- /dev/null
+++ b/project/.idea/misc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/project/.idea/modules.xml b/project/.idea/modules.xml
new file mode 100644
index 0000000..2c20a2f
--- /dev/null
+++ b/project/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/project/.idea/vcs.xml b/project/.idea/vcs.xml
new file mode 100644
index 0000000..6c0b863
--- /dev/null
+++ b/project/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/project/202401070104-张思渊-期末实验报告.md b/project/202401070104-张思渊-期末实验报告.md
new file mode 100644
index 0000000..5095571
--- /dev/null
+++ b/project/202401070104-张思渊-期末实验报告.md
@@ -0,0 +1,638 @@
+# 《高级程序设计》项目报告:
+爬虫项目开发全过程记录
+
+## 一、项目目标
+
+### 1.1 功能目标
+
+| 功能 | 描述 | 优先级 |
+|------|------|--------|
+| 爬取豆瓣电影数据 | 爬取豆瓣电影Top250的电影标题、评分、年份、导演等信息 | 高 |
+| 爬取前程无忧招聘数据 | 爬取Java相关职位的职位名称、公司、薪资、城市、经验要求等信息 | 高 |
+| 爬取古诗词数据 | 爬取古诗词网站的诗词标题、作者、朝代、内容等信息 | 高 |
+| 数据清洗 | 去除HTML标签、空格、特殊字符,格式化日期,处理缺失值 | 高 |
+| 数据存储 | 将清洗后的数据保存为CSV和JSON格式文件 | 高 |
+| 数据分析 | 使用Stream API进行统计分析,如评分分布、薪资分析、高频词提取 | 中 |
+| CLI交互界面 | 实现命令行交互界面,支持用户输入命令操作 | 中 |
+| 结果展示 | 控制台打印统计表格,生成分析报告 | 中 |
+
+### 1.2 预期效果
+
+(1)成功爬取3个不同网站的数据,每个网站至少爬取100条记录。
+(2)数据清洗后保存为结构化文件,便于后续分析。
+(3)通过CLI界面实现交互式操作,支持命令输入。
+(4)提供数据统计分析功能,输出可视化报告。
+(5)实现真正的MVC三层架构分离。
+
+---
+
+## 二、项目进展
+
+### W1:类与对象基础,构造方法与封装
+
+**本周任务:**
+- 实现Movie实体类,包含title、rating、year、director字段
+- 实现Job实体类,包含title、company、location、salary、experience、education字段
+- 实现Poem实体类,包含title、author、dynasty、content字段
+
+**所学知识:**
+- Java封装性原理
+- private关键字的使用
+- Getter和Setter方法的设计
+- 构造方法重载
+
+**遇到的困难:**
+- 觉得Java写Getter/Setter很繁琐,不理解为什么不能像Python一样直接访问属性
+
+**如何解决的:**
+- 通过查找资料和询问ai,理解了封装是为了数据安全和后期维护,确保数据完整性
+
+**AI是如何帮助的:**
+- 将Python类代码喂给AI,AI生成了对应的Java代码
+- AI解释了访问修饰符的作用和封装的意义
+- AI建议了接口设计方案,实现数据处理的统一
+
+---
+
+### W2:继承与方法重写
+
+**本周任务:**
+- 实现AbstractWebCrawler抽象类,包含crawl()和parse()方法
+- 实现MovieCrawler子类,重写父类方法
+- 实现JobCrawler子类,重写父类方法
+- 实现PoemCrawler子类,重写父类方法
+
+**所学知识:**
+- extends关键字实现继承
+- @Override注解标记方法重写
+- super关键字调用父类构造方法
+- 抽象类与抽象方法的定义
+
+**遇到的困难:**
+- 子类构造方法中调用父类构造方法时参数传递错误
+- 抽象方法的实现逻辑不清晰
+
+**如何解决的:**
+- 查阅Java文档,理解super()必须放在构造方法第一行
+- 分析不同网站的HTML结构,设计针对性的解析逻辑
+- 使用正则表达式提取页面数据
+
+**AI是如何帮助的:**
+- AI检查了继承关系的合理性
+- AI生成了类图的Mermaid代码,帮助理解类结构
+- AI提供了正则表达式的编写建议
+
+---
+
+### W3:多态实现
+
+**本周任务:**
+- 通过父类引用调用不同爬虫的爬取方法
+- 使用List统一管理所有爬虫
+- 实现爬虫的动态切换
+
+**所学知识:**
+- 向上转型的概念
+- 动态绑定机制
+- instanceof关键字的使用
+- 多态的实际应用场景
+
+**遇到的困难:**
+- 不理解为什么父类引用可以调用子类重写的方法
+- 不知道如何设计统一的爬虫调度机制
+
+**如何解决的:**
+- 通过调试代码,观察运行时的方法调用过程
+- 理解了多态的本质是运行时类型识别
+- 设计CrawlerManager统一管理爬虫实例
+
+**AI是如何帮助的:**
+- AI用生活化的比喻"遥控器控制不同电器"解释了多态的概念
+- AI演示了多态在实际项目中的应用场景
+- AI帮助设计了爬虫管理类的结构
+
+---
+
+### W4:抽象类与接口
+
+**本周任务:**
+- 设计ICrawler接口
+- 设计IAnalyzer接口
+- 让AbstractWebCrawler实现ICrawler接口
+- 定义DataEntity接口统一数据访问
+
+**所学知识:**
+- interface关键字定义接口
+- implements关键字实现接口
+- 接口与抽象类的区别
+- 接口的多实现特性
+
+**遇到的困难:**
+- 不确定什么时候用抽象类,什么时候用接口
+- 接口方法的设计不够合理
+
+**如何解决的:**
+- 遵循"is-a用抽象类,has-a/can-do用接口"的原则
+- 将爬虫的通用逻辑放在抽象类中,具体行为定义在接口中
+- 通过小组讨论确定接口设计方案
+
+**AI是如何帮助的:**
+- AI演示了如何用接口解耦臃肿的代码
+- AI对比了抽象类和接口的使用场景
+- AI建议了合理的接口设计方案
+
+---
+
+### W5:加入异常处理
+
+**本周任务:**
+- 自定义CrawlerException异常类
+- 自定义ParseException异常类
+- 在Controller层统一捕获异常
+- 给出友好的错误提示
+
+**所学知识:**
+- try-catch-finally异常处理结构
+- throws关键字声明异常
+- 自定义异常类的实现
+- 异常继承体系的设计
+
+**遇到的困难:**
+- 网络请求超时导致程序崩溃,没有友好的错误提示
+- 异常处理逻辑过于分散
+
+**如何解决的:**
+- 封装了CrawlerException,统一处理爬虫相关异常
+- 在Controller层使用try-catch统一捕获异常
+- 设计异常处理中间件,提供友好的错误提示
+
+**AI是如何帮助的:**
+- AI生成了异常体系的骨架代码
+- AI建议了合理的异常继承结构
+- AI帮助设计了异常处理的最佳实践
+
+---
+
+### W6:泛型与集合框架
+
+**本周任务:**
+- 使用List、List、List管理数据
+- 使用Stream API进行数据统计和分析
+- 使用Map进行数据分组和计数
+
+**所学知识:**
+- 泛型类和泛型方法
+- List、Map接口的使用
+- Stream API的链式调用
+- Lambda表达式的应用
+
+**遇到的困难:**
+- Stream API的链式调用容易写错
+- 泛型类型擦除导致编译错误
+- 复杂的数据统计逻辑难以实现
+
+**如何解决的:**
+- 通过IDE的类型提示逐步修正代码
+- 学习Stream API的常用操作方法
+- 将复杂统计逻辑拆分为多个简单步骤
+
+**AI是如何帮助的:**
+- AI将一段传统的for循环代码改写为Stream API风格
+- AI提供了Stream API的常用操作示例
+- AI帮助调试泛型相关的编译错误
+
+---
+
+### W7:实现 CLI + MVC + Command模式 + 策略模式
+
+**本周任务:**
+- 划分Model/View/Controller职责
+- 实现Command接口和具体命令类
+- 实现策略模式处理不同爬取策略
+- 实现CLI交互界面
+
+**所学知识:**
+- MVC架构模式
+- Command设计模式
+- Strategy设计模式
+- CLI交互设计原则
+
+**遇到的困难:**
+- Controller中不小心混入了打印逻辑,违反了MVC原则
+- 命令模式的实现不够灵活
+
+**如何解决的:**
+- 将打印逻辑移到View层
+- 使用Map存储命令实例,实现命令的动态注册
+- 设计命令别名机制,提高用户体验
+
+**AI是如何帮助的:**
+- AI检查了代码的MVC划分,指出问题所在
+- AI提供了Command模式的实现模板
+- AI建议了策略模式的设计方案
+
+---
+
+### W8:文件 I/O 与序列化
+
+**本周任务:**
+- 将数据写入CSV文件
+- 将数据写入JSON文件
+- 支持从文件读取数据
+- 处理文件编码问题
+
+**所学知识:**
+- FileWriter和BufferedWriter的使用
+- JSON数据格式的序列化
+- CSV文件格式规范
+- UTF-8编码处理
+
+**遇到的困难:**
+- CSV文件中包含逗号导致列错位
+- JSON序列化时日期格式错误
+- 文件路径处理复杂
+
+**如何解决的:**
+- 使用双引号包裹含逗号的字段
+- 使用SimpleDateFormat格式化日期
+- 封装DataStorage工具类统一处理文件操作
+
+**AI是如何帮助的:**
+- AI生成了CSV和JSON的读写工具类
+- AI处理了边界情况,如特殊字符转义
+- AI建议了文件路径的最佳实践
+
+---
+
+## 三、项目结构
+
+### 3.1 最终包结构
+
+```
+project/
+├── src/project/
+│ ├── bean/ # Model 数据模型层
+│ │ ├── Movie.java # 电影数据实体
+│ │ ├── Job.java # 招聘数据实体
+│ │ └── Poem.java # 诗词数据实体
+│ │
+│ ├── view/ # View 视图层
+│ │ └── ConsoleView.java # 控制台UI交互
+│ │
+│ ├── controller/ # Controller 控制器层
+│ │ └── CrawlerController.java # 命令调度中心
+│ │
+│ ├── command/ # Command 命令模式
+│ │ ├── Command.java # 命令接口
+│ │ ├── CrawlCommand.java # 爬取命令
+│ │ ├── ListCommand.java # 列表命令
+│ │ ├── AnalyzeCommand.java # 分析命令
+│ │ ├── SaveCommand.java # 保存命令
+│ │ ├── HelpCommand.java # 帮助命令
+│ │ ├── HistoryCommand.java # 历史记录命令
+│ │ └── ExitCommand.java # 退出命令
+│ │
+│ ├── core/ # 核心接口
+│ │ ├── DataEntity.java # 数据实体接口
+│ │ ├── WebCrawler.java # 爬虫接口
+│ │ └── AbstractWebCrawler.java # 爬虫抽象类
+│ │
+│ ├── strategy/ # Strategy 策略模式
+│ │ ├── CrawlStrategy.java # 爬取策略接口
+│ │ ├── CrawlerContext.java # 策略上下文
+│ │ ├── MovieCrawlStrategy.java # 电影爬取策略
+│ │ ├── JobCrawlStrategy.java # 招聘爬取策略
+│ │ └── PoemCrawlStrategy.java # 诗词爬取策略
+│ │
+│ ├── crawler/ # 爬虫实现
+│ │ ├── MovieCrawler.java
+│ │ ├── JobCrawler.java
+│ │ └── PoemCrawler.java
+│ │
+│ ├── analysis/ # 数据分析
+│ │ ├── MovieAnalyzer.java
+│ │ ├── JobAnalyzer.java
+│ │ └── PoemAnalyzer.java
+│ │
+│ ├── utils/ # 工具类
+│ │ ├── HttpUtils.java
+│ │ ├── DataCleaner.java
+│ │ └── DataStorage.java
+│ │
+│ ├── exception/ # 异常类
+│ │ ├── CrawlerException.java
+│ │ └── ParseException.java
+│ │
+│ ├── Main.java # 主入口(CLI交互)
+│ └── AutoTest.java # 自动测试
+│
+├── bin/ # 编译输出目录
+└── output/ # 数据输出目录
+```
+
+### 3.2 MVC架构说明
+
+| 层 | 包/类 | 职责 | 只做什么 |
+|---|-------|------|----------|
+| **Model** | `bean/*` | 数据模型 | 存储数据、提供getter/setter |
+| **View** | `view/ConsoleView` | 用户界面 | 打印菜单、读取输入、展示结果 |
+| **Controller** | `controller/*` | 业务调度 | 接收命令、调用Command执行 |
+| **Command** | `command/*` | 命令执行 | 实现具体业务逻辑 |
+
+### 3.3 设计模式
+
+#### 3.3.1 Command模式
+
+| 组件 | 职责 |
+|------|------|
+| `Command` 接口 | 定义命令的执行接口 |
+| `CrawlCommand` | 爬取数据命令 |
+| `ListCommand` | 显示列表命令 |
+| `AnalyzeCommand` | 分析数据命令 |
+| `SaveCommand` | 保存数据命令 |
+
+#### 3.3.2 Strategy模式
+
+| 组件 | 职责 |
+|------|------|
+| `CrawlStrategy` 接口 | 定义爬取策略接口 |
+| `CrawlerContext` | 策略上下文,管理所有策略 |
+| `MovieCrawlStrategy` | 电影爬取策略 |
+| `JobCrawlStrategy` | 招聘爬取策略 |
+| `PoemCrawlStrategy` | 诗词爬取策略 |
+
+**策略模式类图:**
+
+```mermaid
+classDiagram
+ class CrawlStrategy~T extends DataEntity~ {
+ <>
+ +getType() String
+ +getTypeName() String
+ +crawl(int pages) List~T~
+ }
+
+ class CrawlerContext {
+ -Map~String, CrawlStrategy~~ strategies
+ +registerStrategy(CrawlStrategy) void
+ +getStrategy(String) CrawlStrategy~T~
+ +hasStrategy(String) boolean
+ }
+
+ class MovieCrawlStrategy {
+ -MovieCrawler crawler
+ +getType() String
+ +getTypeName() String
+ +crawl(int pages) List~Movie~
+ }
+
+ class JobCrawlStrategy {
+ -JobCrawler crawler
+ +getType() String
+ +getTypeName() String
+ +crawl(int pages) List~Job~
+ }
+
+ class PoemCrawlStrategy {
+ -PoemCrawler crawler
+ +getType() String
+ +getTypeName() String
+ +crawl(int pages) List~Poem~
+ }
+
+ CrawlStrategy <|.. MovieCrawlStrategy
+ CrawlStrategy <|.. JobCrawlStrategy
+ CrawlStrategy <|.. PoemCrawlStrategy
+ CrawlerContext --> CrawlStrategy : uses
+```
+
+#### 3.3.4 异常体系说明
+**类层次结构**
+```
+java.lang.Exception
+ │
+ └── CrawlerException (爬虫异常)
+ │
+ └── ParseException (解析异常)
+```
+**异常链路传播**
+```
+┌─────────────────────────────────────────────────────────────┐
+│ 用户输入 │
+│ "crawl movie" │
+└───────────────────────────┬─────────────────────────────────┘
+ ↓
+┌─────────────────────────────────────────────────────────────┐
+│ CrawlCommand │
+│ .execute() │
+│ throws CrawlerException │
+└───────────────────────────┬─────────────────────────────────┘
+ ↓
+┌─────────────────────────────────────────────────────────────┐
+│ MovieCrawlStrategy.crawl() │
+│ throws CrawlerException │
+└───────────────────────────┬─────────────────────────────────┘
+ ↓
+┌─────────────────────────────────────────────────────────────┐
+│ MovieCrawler (extends AbstractWebCrawler) │
+│ .crawl() │
+│ throws CrawlerException │
+└───────────────────────────┬─────────────────────────────────┘
+ ↓
+┌─────────────────────────────────────────────────────────────┐
+│ AbstractWebCrawler │
+│ .crawlSingleThread() │
+│ throws CrawlerException │
+└───────────────────────────┬─────────────────────────────────┘
+ ↓
+┌─────────────────────────────────────────────────────────────┐
+│ HttpUtils │
+│ .fetchHtml() │
+│ throws CrawlerException │
+│ │
+│ 可能的异常: │
+│ - HTTP 404/500/403 │
+│ - 连接超时 │
+│ - URL无效 │
+│ - 网络不可达 │
+└─────────────────────────────────────────────────────────────┘
+```
+
+### 3.4 完整类图
+
+```mermaid
+classDiagram
+ class ConsoleView {
+ <>
+ +readCommand() String
+ +printWelcome() void
+ +printHelp() void
+ +printMovieList(List) void
+ +printJobList(List) void
+ +printPoemList(List) void
+ +printSuccess(String) void
+ +printError(String) void
+ }
+
+ class CrawlerController {
+ <>
+ -Map~String, Command~ commands
+ -Map~String, String~ aliases
+ -List~String~ history
+ +execute(String) void
+ +getMovies() List~Movie~
+ +getJobs() List~Job~
+ +getPoems() List~Poem~
+ +isExitCommand(String) boolean
+ }
+
+ class Command {
+ <>
+ +execute(String[]) void
+ +getName() String
+ +getDescription() String
+ }
+
+ class CrawlCommand {
+ +execute(String[]) void
+ }
+
+ class ListCommand {
+ +execute(String[]) void
+ }
+
+ class AnalyzeCommand {
+ +execute(String[]) void
+ }
+
+ class SaveCommand {
+ +execute(String[]) void
+ }
+
+ class HelpCommand {
+ +execute(String[]) void
+ }
+
+ class HistoryCommand {
+ +execute(String[]) void
+ }
+
+ class ExitCommand {
+ +execute(String[]) void
+ }
+
+ class MovieCrawler {
+ +parsePage(String, int) List~Movie~
+ }
+
+ class JobCrawler {
+ +parsePage(String, int) List~Job~
+ }
+
+ class PoemCrawler {
+ +parsePage(String, int) List~Poem~
+ }
+
+ ConsoleView --> CrawlerController : uses
+ CrawlerController --> Command : uses
+ Command <|.. CrawlCommand
+ Command <|.. ListCommand
+ Command <|.. AnalyzeCommand
+ Command <|.. SaveCommand
+ Command <|.. HelpCommand
+ Command <|.. HistoryCommand
+ Command <|.. ExitCommand
+ CrawlCommand --> MovieCrawler : creates
+ CrawlCommand --> JobCrawler : creates
+ CrawlCommand --> PoemCrawler : creates
+```
+
+---
+
+## 四、成果展示
+
+### 4.1 运行截图
+**编译**
+
+**爬取**
+
+**查看**
+
+
+
+**分析**
+
+**保存**
+
+**查看历史命令和退出**
+
+### 4.2 功能测试
+
+| 功能 | 测试结果 | 备注 |
+|------|----------|------|
+| 豆瓣电影爬虫 | ✅ 通过 | 成功爬取75部电影数据 |
+| 前程无忧招聘爬虫 | ✅ 通过 | 成功爬取20条招聘信息 |
+| 古诗词爬虫 | ✅ 通过 | 成功爬取20首诗词 |
+| MVC架构 | ✅ 通过 | View/Controller/Command完全分离 |
+| CLI交互 | ✅ 通过 | 支持命令输入和快捷键 |
+| Command模式 | ✅ 通过 | 7个独立命令类 |
+| 策略模式 | ✅ 通过 | 实现爬虫策略的动态切换 |
+| 异常体系 | ✅ 通过 | 实现爬虫相关错误和数据解析错误|
+| 数据清洗 | ✅ 通过 | 去除HTML标签、空格、特殊字符 |
+| CSV文件保存 | ✅ 通过 | 生成movies.csv, jobs.csv, poems.csv |
+| JSON文件保存 | ✅ 通过 | 生成movies.json, jobs.json, poems.json |
+| 数据分析 | ✅ 通过 | Stream API统计分析 |
+| 命令历史 | ✅ 通过 | 记录用户输入的命令 |
+| 命令别名 | ✅ 通过 | c/l/a/s/h等快捷键 |
+
+---
+
+## 五、总结
+
+### 5.1 项目完成情况
+
+本项目成功实现了一个完整的多源数据爬取与分析系统,主要完成内容包括:
+
+1. **爬虫模块**:实现了三个网站的爬虫(豆瓣电影、前程无忧、古诗词网),支持分页爬取
+2. **数据模型**:设计了Movie、Job、Poem三个实体类,实现DataEntity接口统一处理
+3. **MVC架构**:实现了真正的三层分离
+ - Model层:bean包 - 数据存储
+ - View层:view包 - UI交互
+ - Controller层:controller包 - 业务调度
+4. **Command模式**:7个独立命令类实现具体业务逻辑
+5. **策略模式**:通过CrawlStrategy接口和CrawlerContext实现爬虫策略的动态切换
+6. **CLI交互**:支持命令输入、快捷键、命令历史
+7. **数据存储**:支持CSV和JSON两种格式的文件输出
+8. **数据分析**:使用Stream API进行数据统计
+
+### 5.2 技术亮点
+
+- **真正的MVC分离**:View层不包含任何业务逻辑,Controller只负责调度,Command实现具体业务
+- **Command模式**:每个命令封装成独立类,便于扩展和维护
+- **策略模式**:通过CrawlStrategy接口和CrawlerContext实现爬虫策略的动态切换,支持运行时更换爬取算法
+- **命令别名**:支持快捷键(c/l/a/s/h),提升用户体验
+- **命令历史**:记录用户输入的所有命令
+- **泛型编程**:通过泛型实现爬虫的类型安全
+- **Stream API**:简化数据统计分析代码
+
+### 5.3 后续改进方向
+
+1. **引入Jsoup库**:使用专业的HTML解析库替代正则表达式
+2. **数据库持久化**:添加MySQL/SQLite支持,实现数据持久化存储
+3. **图表生成**:使用JFreeChart或XChart生成可视化图表
+4. **分布式爬取**:支持分布式爬虫架构
+5. **API接口**:提供RESTful API接口供外部系统调用
+
+### 5.4 学习收获
+
+通过本次项目开发,我掌握了以下技能:
+
+- Java面向对象编程的核心概念(封装、继承、多态)
+- 设计模式的实际应用(MVC模式、Command模式、策略模式)
+- MVC架构的真正含义和实践
+- CLI界面设计和用户交互
+- 网络编程和HTTP请求处理
+- 数据清洗和格式化处理
+- 文件I/O和数据序列化
+- 异常处理和错误恢复
+---
\ No newline at end of file
diff --git a/project/202401070104-张思渊-期末实验报告docx.docx b/project/202401070104-张思渊-期末实验报告docx.docx
new file mode 100644
index 0000000000000000000000000000000000000000..bf713a12c13ecdccef723b399055f7c49242e025
GIT binary patch
literal 788757
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
z |