# 豆瓣电影Top250数据爬取与可视化分析实验报告 ## 一、实验名称 豆瓣电影Top250数据爬取、分析及可视化实现 ## 二、实验目的 1. 掌握基于Jsoup的Java网络爬虫开发方法,实现静态网页的目标数据提取与清洗; 2. 熟练运用Java Stream API进行数据的统计与分析,实现数据的多维度挖掘; 3. 学会使用OpenCSV实现结构化数据的CSV文件导出,完成数据的持久化存储; 4. 掌握XChart可视化工具的使用,实现柱状图、折线图、饼图的绘制与图片保存; 5. 理解面向对象思想在项目中的应用,完成实体类、工具类的分层设计与开发。 ## 三、实验环境 1. **开发语言**:Java 22.0.1 2. **开发工具**:IntelliJ IDEA(或Eclipse) 3. **核心依赖**: - Jsoup 1.17.2:网页解析与数据爬取 - OpenCSV 5.8:CSV文件导出 - XChart 3.8.7:数据可视化图表绘制 4. **运行系统**:Windows 10/11(兼容Linux/Mac OS) 5. **目标爬取网站**:豆瓣电影Top250([https://movie.douban.com/top250](https://movie.douban.com/top250)) ## 四、实验原理 1. **网络爬虫原理**:通过Jsoup模拟浏览器发送HTTP请求,获取豆瓣电影Top250网页的HTML文档,利用CSS选择器定位目标标签,提取电影名称、导演、上映年份、评分、评价人数等原始数据,再通过正则表达式、字符串切割等方式完成数据清洗,得到结构化数据。 2. **数据处理原理**:基于Java Stream API对爬取的结构化数据进行流式操作,实现数据的过滤、排序、分组、统计,完成评分Top10、年份电影数量、评分分布等多维度分析。 3. **数据持久化原理**:通过OpenCSV将结构化的电影数据按指定字段格式写入CSV文件,实现数据的本地持久化,支持Excel/WPS等工具直接打开查看。 4. **数据可视化原理**:利用XChart工具将分析后的统计数据映射为柱状图、折线图、饼图,通过设置图表样式、坐标轴、标题等属性,将抽象数据转化为直观的图形,并保存为PNG图片格式。 ## 五、实验内容与步骤 ### (一)项目结构设计 采用面向对象分层设计思想,将项目分为**实体类、爬虫工具类、数据分析类、CSV导出类、可视化图表类、主程序类**,各模块职责单一,降低耦合度,项目最终结构如下: ```Plain Text com.example.crawl/ ├── Movie.java // 电影实体类,封装数据属性 ├── DoubanCrawler.java // 爬虫工具类,实现数据爬取与清洗 ├── DataAnalyzer.java // 数据分析类,实现数据统计分析 ├── CsvExporter.java // CSV导出类,实现数据持久化 ├── ChartGenerator.java // 可视化类,实现图表绘制与保存 └── Main.java // 主程序类,统一调用各模块功能 ``` ### (二)核心依赖配置 通过Maven管理项目依赖,在`pom.xml`中配置Jsoup、OpenCSV、XChart的依赖坐标,实现第三方库的自动导入,核心配置代码如下: ```XML org.jsoup jsoup 1.17.2 com.opencsv opencsv 5.8 org.knowm.xchart xchart 3.8.7 ``` ### (三)模块开发实现 #### 1. 电影实体类(Movie.java) 定义与电影数据对应的属性:电影名称、导演、上映年份、评分、评价人数,提供无参/全参构造方法、Getters/Setters方法及toString()方法,实现数据的封装与访问。 #### 2. 爬虫工具类(DoubanCrawler.java) 1. 定义豆瓣电影Top250基础请求URL,通过循环实现10页数据的分页爬取(每页25条,共250条); 2. 设置请求头`User-Agent`模拟浏览器,添加随机延时`Thread.sleep()`实现文明爬虫,避免请求过快被封; 3. 利用Jsoup CSS选择器定位目标标签,提取原始数据,解决豆瓣页面结构导致的元素定位问题; 4. 通过正则表达式提取上映年份、评价人数,通过字符串切割清洗导演信息,处理空指针异常,保证数据提取的稳定性; 5. 最终返回封装好的`List`结构化数据列表。 #### 3. 数据分析类(DataAnalyzer.java) 基于Java Stream API实现三大核心分析功能: 1. 数据总览:统计电影总数、计算平均评分; 2. 评分Top10:按评分降序排序,获取评分最高的10部电影; 3. 年份分布:按上映年份分组,统计各年份的电影产出数量,并按年份升序输出。 #### 4. CSV导出类(CsvExporter.java) 1. 定义CSV文件导出路径与表头(电影名称、导演、上映年份、豆瓣评分、评价人数); 2. 遍历`List`数据,将每部电影的属性按表头顺序写入CSV文件; 3. 实现CSV特殊字符转义处理,避免逗号、引号导致的文件格式错乱; 4. 完成数据的本地持久化,支持Excel/WPS直接打开。 #### 5. 可视化图表类(ChartGenerator.java) 基于XChart实现三种常用图表的绘制,解决XChart折线图X轴数据类型限制、中文显示等问题: 1. 年份电影数量柱状图:筛选1980年后的数据,取前15个年份,展示各年份电影产出数量; 2. 历年平均评分折线图:按年份分组计算平均评分,以数字类型为X轴,展示评分趋势变化; 3. 评分分布饼图:将电影按9.5分及以上、9.0-9.5分、9.0分以下分组,展示各评分段的电影占比。 所有图表均设置合理的宽高、标题、坐标轴标签,保存为PNG格式至项目根目录。 #### 6. 主程序类(Main.java) 作为项目入口,按**爬取→测试→分析→导出→可视化**的流程统一调用各模块方法,实现整个实验的自动化执行,核心执行逻辑如下: 1. 调用爬虫类爬取250部电影数据; 2. 打印第一部电影的评价人数,验证爬取结果有效性; 3. 调用分析类完成数据多维度统计并控制台输出; 4. 调用CSV导出类将数据保存为本地文件; 5. 调用可视化类绘制并保存柱状图、折线图、饼图。 ### (四)项目运行与调试 1. 解决爬取阶段**评价人数提取失败**问题:因豆瓣页面结构,放弃固定索引定位,改为抓取电影卡片全部文字并通过正则强匹配`XXX人评价`,确保评价人数精准提取; 2. 解决CSV导出**字段顺序错乱**问题:修正字段写入顺序,保证与表头完全对应,解决评价人数字段显示为0的视觉问题; 3. 解决可视化阶段**Java版本兼容**问题:移除`var`关键字,改为显式类型声明,兼容Java 8及以上版本; 4. 解决折线图**数据类型报错**问题:将X轴字符串类型改为数字类型(Integer),符合XChart折线图数据类型要求,解决`Series data must be either Number or Date type`异常。 ## 六、实验结果与分析 ### (一)数据爬取结果 成功爬取豆瓣电影Top250全部250部电影的结构化数据,包括电影名称、导演、上映年份、豆瓣评分、评价人数,无数据缺失、无空指针异常,爬取结果验证有效(如《肖申克的救赎》评价人数3037887、评分9.7,《霸王别姬》评价人数2245306、评分9.6)。 ### (二)数据统计分析结果 1. **数据总览**:共获取250部电影,平均评分为8.95分,整体评分水平较高,体现豆瓣Top250电影的优质性; 2. **评分Top10**:评分最高的电影为《肖申克的救赎》(9.7分),其次为《霸王别姬》《控方证人》(均9.6分),9.5分及以上电影共9部,均为经典高分作品; 3. **年份分布**:1994年、2004年、2010年为产出高峰,分别有12部、13部、14部电影上榜;1980年后电影占比超90%,反映经典电影的时间分布特征。 ### (三)数据持久化结果 成功导出`douban_top250.csv`文件,文件包含250条数据记录,5个核心字段,字段顺序正确、格式规范,可通过Excel/WPS直接打开查看、编辑,实现了数据的本地持久化存储。 ### (四)数据可视化结果 成功生成3张可视化图表并保存为PNG图片,图表样式规范、数据直观: 1. **年份电影数量柱状图**:清晰展示1980年后各年份的电影产出数量,可直观看到2004年、2010年等高峰年份; 2. **历年平均评分折线图**:展示各年份豆瓣Top250电影的平均评分趋势,整体评分保持在8.8-9.2分之间,波动较小,说明经典电影的评分稳定性; 3. **评分分布饼图**:9.0-9.5分电影占比最高(约70%),9.5分及以上电影占比约3.6%,9.0分以下电影占比约26.4%,体现豆瓣Top250的评分门槛较高。 ## 七、实验问题与解决方法 本次实验过程中遇到多个技术问题,通过分析问题根源、调试代码实现了全部解决,具体问题与解决方法如下表所示: |序号|问题描述|问题根源|解决方法| |---|---|---|---| |1|爬取评价人数时出现空指针异常|豆瓣页面结构导致固定索引定位元素失败|放弃固定索引,抓取电影卡片全部文字,通过正则表达式强匹配`XXX人评价`提取人数| |2|CSV文件中评价人数全显示为0|CSV导出时字段顺序与表头不一致,赋值错误|修正字段写入顺序,保证与表头一一对应,添加字段赋值校验| |3|可视化代码编译报错,提示无法解析`var`|部分开发环境对Java高版本语法支持不佳|移除`var`关键字,改为显式类型声明,兼容Java 8及以上版本| |4|绘制折线图时抛出`IllegalArgumentException`|XChart折线图不支持字符串类型X轴,要求为数字/日期类型|将X轴`List`改为`List`(年份数字),符合数据类型要求| |5|爬取数据时请求被限制,页面获取失败|请求频率过快,豆瓣反爬机制拦截|添加随机延时`Thread.sleep(1000-3000ms)`,设置`User-Agent`模拟浏览器| ## 八、实验总结与体会 本次实验基于Java语言完成了豆瓣电影Top250从**数据爬取→数据清洗→数据分析→数据持久化→数据可视化**的全流程实现,综合运用了Jsoup、Stream API、OpenCSV、XChart等技术,实现了多模块的分层开发与协同运行。 通过本次实验,我深入掌握了Java网络爬虫的开发流程,理解了静态网页数据提取的核心原理,学会了处理网页结构变化、反爬机制等实际问题;熟练运用Stream API实现了高效的数据统计分析,体会到流式编程在数据处理中的简洁性与高效性;掌握了OpenCSV的使用方法,实现了结构化数据的持久化;学会了XChart可视化工具的基本用法,理解了“数据可视化”将抽象数据转化为直观图形的核心价值,同时解决了开发过程中的版本兼容、数据类型、异常处理等多个实际问题。 在实验过程中,我深刻认识到**面向对象分层设计**的重要性,将项目按功能拆分为多个独立模块,不仅提高了代码的可读性、可维护性,也便于问题定位与调试;同时,**异常处理**和**边界条件校验**是保证程序稳定性的关键,如爬取时的空指针处理、数据清洗时的正则匹配、可视化时的数据类型校验,缺一不可。此外,网络爬虫开发需遵循**文明爬虫**原则,设置合理的请求延时、模拟浏览器请求,避免对目标网站造成服务器压力。 本次实验也让我认识到,实际开发中网页结构、第三方库语法、开发环境等均可能出现预期外问题,需要具备**问题分析能力**和**调试能力**,通过查看官方文档、调试代码、分析报错信息等方式解决问题。后续可在此实验基础上进行功能拓展,如爬取电影主演、简介、类型等更多数据,实现按导演、国家/地区的统计分析,绘制更多维度的可视化图表,进一步提升数据挖掘与分析能力。 ## 九、实验拓展方向 1. 拓展爬取字段:增加电影主演、剧情简介、电影类型、制片国家/地区等数据,丰富数据维度; 2. 增强数据分析:实现按导演、国家/地区、电影类型的统计分析,挖掘经典电影的导演、地域分布特征; 3. 优化可视化效果:添加图表中文乱码解决方案、自定义图表颜色/样式,实现更美观的可视化效果; 4. 增加数据校验:实现爬取数据的重复校验、缺失值处理,提升数据质量; 5. 开发图形界面:基于JavaFX/Swing开发简单的图形界面,实现“一键爬取→分析→可视化”的可视化操作。 > (注:文档部分内容可能由 AI 生成)