ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

电影票房大数据分析与可视化实战:Python+Spark+Hadoop

2026/8/30 19:09:34 拓冰建站 浏览量
电影票房大数据分析与可视化实战:Python+Spark+Hadoop 电影票房数据分析与可视化是计算机毕业设计里比较经典的大数据选题。它把 Python 爬虫、Hadoop、Spark、可视化串联成一条完整的数据处理链路爬虫负责采集数据Hadoop 负责存储海量历史数据Spark 负责清洗和统计分析最后通过 Web 页面把票房趋势、影片排行、类型分布展示出来。对于想体现“大数据全流程”能力的学生来说这个选题不需要太复杂的算法但能很好地覆盖数据采集、存储、计算、展示四个环节答辩时也容易讲清楚。这篇文章不会空谈概念直接给出一套可以从 0 到 1 去落地的技术路线包括环境准备、爬虫采集、HDFS 存储、Spark 分析、可视化展示的代码骨架以及配套的测试方法和常见问题排查思路。无论是做毕业设计还是课程设计都可以参考这个流程来搭建自己的项目。1. 核心能力速览能力项说明项目类型大数据分析与可视化系统适合计算机毕业设计、课程设计核心技术栈Python、Scrapy/Requests、Hadoop HDFS、Hive、Spark SQL、Flask、ECharts主要功能票房数据采集、数据清洗、数据入库、HDFS 存储、Spark 统计分析、可视化大屏展示数据规模支持百万级票房记录取决于 Hadoop/Spark 集群资源配置推荐运行环境Linux 服务器或虚拟机16G 内存以上4 核 CPU 以上纯测试可用单机伪分布式启动方式命令启动先启动 Hadoop再运行 Spark 分析脚本最后启动 Flask Web 服务是否支持批量任务支持爬虫可批量采集多页数据Spark 可批量处理多维度统计是否提供 API可扩展Flask 可提供 JSON 接口供前端调用适合人群计算机相关专业本科生、大数据方向初学者、需要快速搭建毕设原型的学生需要注意实际部署所需的硬件配置和内存占用取决于采集数据量、Hadoop 集群节点数、Spark 任务并发度。下面给出的环境清单是通用参考具体版本需要按本机条件调整。2. 适用场景与使用边界这个选题适合以下几类场景计算机专业毕业设计需要体现大数据处理全流程。大数据课程设计要求使用 Hadoop 或 Spark 完成一个具体业务分析。想快速熟悉 Python 爬虫 分布式存储 数据分析的入门项目。需要做可视化大屏展示同时具备 Web 页面开发能力的学生。能解决的问题自动采集主流电影票房平台的历史票房、实时票房、影片信息、类型、地区、上映日期等数据。将数据从 CSV 文件导入 HDFS通过 Spark SQL 完成总票房、平均票房、年度票房、类型票房占比等统计。使用 ECharts 展示票房趋势图、影片 TOP10 榜单、类型占比饼图形成可视化的分析报告。使用边界和合规要求爬虫只能采集公开可访问的数据不能绕过登录验证、不能高频请求导致目标服务器压力过大。要遵守目标网站的 robots.txt 规则并在代码中设置合理的请求间隔。如果使用第三方票房平台的数据需要确认数据版权是否允许二次分析和发布。如果项目中包含用户注册、评论等个人信息必须做脱敏处理不能直接展示隐私数据。本系统仅用于学习与研究不能将采集到的数据用于商业用途或侵犯平台权益。3. 系统总体架构与功能模块从数据流向来看整个系统分为四层数据采集层 - 数据存储层 - 数据分析层 - 数据展示层。数据采集层使用 Python 编写爬虫从电影票房网站抓取每日票房、累计票房、影片名称、类型、上映天数、票房占比等信息。抓取到的数据以 CSV 格式保存或者直接写入 MySQL 数据库。数据存储层使用 Hadoop HDFS 作为分布式文件系统存放原始 CSV 文件。如果项目需要更复杂的查询可以在此基础上使用 Hive 建立外部表把 HDFS 上的结构化数据映射成表方便 Spark SQL 处理。数据分析层使用 Spark SQL 和 DataFrame API 完成数据清洗与统计。典型任务包括清洗空值、去重、格式统一。统计总票房、平均票价、场均人次。按年份、月份、影片类型、制片地区等多维度聚合。计算票房占比、同比、环比等指标。数据展示层使用 Flask 搭建 Web 服务后端从 Spark 分析结果或 MySQL 聚合结果中读取数据通过 JSON 接口传给前端前端使用 ECharts 渲染图表。整体架构可以用一句话概括Python 爬虫采集数据 - Hadoop 存数据 - Spark 算数据 - Flask ECharts 展示数据。下面给出一个功能模块清单模块功能技术实现数据采集模块定时抓取票房数据Python Requests/Scrapy数据清洗模块去重、补全、格式校验Pandas 或 Spark DataFrame数据存储模块保存原始数据和分析结果MySQL、HDFS、Hive分布式计算模块多维度票房统计Hadoop MapReduce / Spark SQL可视化模块图表展示与交互Flask ECharts系统管理模块数据导入、任务触发、日志查看Shell 脚本 Web 页面4. 环境准备与前置条件在开始写代码之前先确认本机或服务器的基础环境是否可以满足 Hadoop 和 Spark 的运行要求。推荐环境清单如下版本号需要根据实际安装情况调整操作系统Ubuntu 20.04 / CentOS 7 或 Windows 10Windows 下建议使用 WSL2 或虚拟机JDKJDK 8 或 JDK 11Hadoop 和 Spark 依赖 Java 环境Hadoop3.x配置为单机伪分布式或集群模式Spark3.x使用 local 模式或 YARN 模式运行Python3.8 或更高版本数据库MySQL 8.x用于存储清洗后的分析结果可视化依赖Flask、PyMySQL、Flask-CORS爬虫依赖requests、BeautifulSoup4、lxml环境检查命令java -version hadoop version spark-submit --version python --version mysql --version如果还没有安装 Hadoop 和 Spark可以在网上搜索安装教程这里不展开安装细节。需要注意Hadoop 的配置文件core-site.xml、hdfs-site.xml、yarn-site.xml需要按本机 IP 和端口修改不要直接复制别人的配置。环境准备完成后还需要规划好项目目录结构movie_analysis/ ├── crawler/ # 爬虫代码 │ ├── movie_crawler.py │ └── data/ │ └── boxoffice.csv ├── data_process/ # 数据清洗脚本 │ └── clean_data.py ├── spark_analysis/ # Spark 分析脚本 │ └── boxoffice_stats.py ├── web/ # Flask Web 服务 │ ├── app.py │ ├── static/ │ └── templates/ ├── hadoop_data/ # 上传到 HDFS 的临时目录 └── output/ # 分析结果输出5. 数据采集Python 爬虫实现票房数据抓取爬虫是这个项目的数据入口。以下代码是通用框架实际采集时需要替换为目标网站的 URL、解析规则和字段名。import csv import time import requests from bs4 import BeautifulSoup def fetch_page(url): headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) } response requests.get(url, headersheaders, timeout10) response.encoding utf-8 return response.text def parse_boxoffice(html): soup BeautifulSoup(html, lxml) rows [] # 根据目标网站的 HTML 结构解析数据 for item in soup.select(.movie-item): title item.select_one(.name).text.strip() box item.select_one(.box).text.strip() date item.select_one(.date).text.strip() rows.append([title, box, date]) return rows def save_to_csv(rows, filenameboxoffice.csv): with open(filename, a, newline, encodingutf-8) as f: writer csv.writer(f) writer.writerows(rows) if __name__ __main__: for page in range(1, 6): url fhttps://example.com/boxoffice?page{page} html fetch_page(url) data parse_boxoffice(html) save_to_csv(data) print(f第 {page} 页完成共 {len(data)} 条数据) time.sleep(2) # 控制请求频率避免给目标服务器造成压力这段代码的核心逻辑是构造请求头 - 获取页面 HTML - 使用 BeautifulSoup 解析目标字段 - 保存到 CSV。在实际项目中你还需要加入异常处理、重试机制和代理池防止爬虫中断。如果数据源接口返回的是 JSON 数据可以直接使用json.loads()解析不需要 BeautifulSoup。爬虫开发完成后建议先用单页测试确认能正确解析字段再扩展到多页批量爬取。批量爬取时一定要设置合理的请求间隔并记录日志。6. 数据入库与清洗原始爬虫数据通常会存在空值、重复数据、格式不一致等问题。推荐先用 Pandas 做初步清洗再导入 Hadoop 或数据库。清洗流程读取 CSV 文件。去掉全空行和重复记录。统一日期格式将字符串转为datetime。处理缺失值票房为空的记录可以删除或者用 0 填充。转换数据类型票房字段从字符串转为 float方便后续计算。示例代码import pandas as pd def clean_data(input_path, output_path): df pd.read_csv(input_path, encodingutf-8) # 去掉重复记录 df df.drop_duplicates() # 删除票房为空的行 df df.dropna(subset[box]) # 统一日期格式 df[date] pd.to_datetime(df[date], format%Y-%m-%d) # 票房转为数值类型去掉逗号等字符 df[box] df[box].astype(str).str.replace(,, ).astype(float) # 输出清洗后的数据 df.to_csv(output_path, indexFalse, encodingutf-8) print(f清洗完成剩余 {len(df)} 条记录) if __name__ __main__: clean_data(crawler/data/boxoffice.csv, crawler/data/boxoffice_clean.csv)清洗后的 CSV 可以同时用于两个方向一是直接上传到 HDFS供 Spark 读取二是导入 MySQL供 Flask 后端做快速查询。如果数据量不大也可以只存 MySQLHDFS 和 Spark 作为加分项展示。7. 数据存储上传 HDFS 并创建 Hive 表把清洗后的数据上传到 HDFShdfs dfs -mkdir -p /movie/boxoffice hdfs dfs -put crawler/data/boxoffice_clean.csv /movie/boxoffice/ hdfs dfs -ls /movie/boxoffice/上传成功说明 HDFS 文件系统可以正常使用。如果项目中使用 Hive可以在 Hive 中创建外部表把 HDFS 上的 CSV 映射成结构化表CREATE EXTERNAL TABLE IF NOT EXISTS movie_boxoffice ( title STRING, box DOUBLE, date STRING ) ROW FORMAT DELIMITED FIELDS TERMINATED BY , STORED AS TEXTFILE LOCATION /movie/boxoffice;这里需要注意CSV 中的字段顺序要和建表顺序一致否则会导致数据错位。如果 CSV 包含表头建议在 create table 语句中用tblproperties (skip.header.line.count1)跳过第一行或者在上传前删除表头。如果不想安装 Hive也可以直接在 Spark 中读取 CSV通过 inferSchema 自动识别类型不依赖 Hive 表。8. 数据分析Spark SQL 与 DataFrameSpark 分析是整个项目的核心。推荐使用 pyspark 的 DataFrame API 和 Spark SQL代码简单便于答辩演示。以下示例展示了读取 HDFS 上的 CSV、注册临时表、执行多维统计。from pyspark.sql import SparkSession from pyspark.sql.functions import sum, avg, count, col def main(): spark SparkSession.builder \ .appName(MovieBoxOfficeAnalysis) \ .master(local[*]) \ .getOrCreate() # 读取 HDFS 上的 CSV 文件自动推断类型 df spark.read \ .option(header, True) \ .option(inferSchema, True) \ .csv(/movie/boxoffice/boxoffice_clean.csv) df.createOrReplaceTempView(boxoffice) # 1. 总票房统计 total spark.sql( SELECT SUM(box) AS total_box FROM boxoffice ) total.show() # 2. 按日期统计票房趋势 daily spark.sql( SELECT date, SUM(box) AS daily_box FROM boxoffice GROUP BY date ORDER BY date ) daily.show() # 3. 按标题统计累计票房并取 TOP10 top10 df.groupBy(title) \ .agg(sum(box).alias(total_box)) \ .orderBy(col(total_box).desc()) \ .limit(10) top10.show() # 将结果保存到本地输出目录 daily.write.mode(overwrite).csv(/movie/output/daily) top10.write.mode(overwrite).csv(/movie/output/top10) spark.stop() if __name__ __main__: main()提交 Spark 任务spark-submit \ --master local[2] \ --name MovieBoxOfficeAnalysis \ spark_analysis/boxoffice_stats.py如果使用 YARN 模式需要把--master改为yarn并确保集群资源足够。除了这些基本统计你还可以扩展以下分析维度按影片类型统计票房占比。按上映月份统计月度总票房。按制片地区统计平均票房。分析票房与上映天数之间的关系。使用线性回归预测未来一周票房。扩展方向不需要太复杂重点是展示你能用 Spark 完成数据聚合和结果输出。9. 数据可视化Flask ECharts 展示分析结果可视化层是用户在浏览器中看到的页面。推荐使用 Flask 提供后端接口ECharts 负责图表渲染。先准备 Flask 后端把 Spark 分析结果读出来以 JSON 格式返回给前端。from flask import Flask, render_template, jsonify import pandas as pd app Flask(__name__) def load_result(path): # 读取 Spark 输出的 CSV 目录实际生成的是 part-xxx 文件 all_files [f{path}/{f} for f in os.listdir(path) if f.startswith(part-)] df_list [pd.read_csv(f, headerNone) for f in all_files] return pd.concat(df_list, ignore_indexTrue) app.route(/) def index(): return render_template(index.html) app.route(/api/daily) def daily_api(): df load_result(output/daily) df.columns [date, value] return jsonify({dates: df[date].tolist(), values: df[value].tolist()}) app.route(/api/top10) def top10_api(): df load_result(output/top10) df.columns [name, value] return jsonify({names: df[name].tolist(), values: df[value].tolist()}) if __name__ __main__: app.run(host0.0.0.0, port5000, debugTrue)前端页面index.html中引入 ECharts通过 fetch 获取接口数据并渲染。!DOCTYPE html html langzh head meta charsetUTF-8 title电影票房分析/title script srchttps://cdn.jsdelivr.net/npm/echarts5/dist/echarts.min.js/script /head body h2电影票房数据分析系统/h2 div iddailyChart stylewidth:100%;height:400px;/div div idtopChart stylewidth:100%;height:400px;/div script async function initChart() { const dailyRes await fetch(/api/daily); const dailyData await dailyRes.json(); const dailyChart echarts.init(document.getElementById(dailyChart)); dailyChart.setOption({ title: { text: 每日票房趋势 }, xAxis: { type: category, data: dailyData.dates }, yAxis: { type: value }, series: [{ type: line, data: dailyData.values }] }); const topRes await fetch(/api/top10); const topData await topRes.json(); const topChart echarts.init(document.getElementById(topChart)); topChart.setOption({ title: { text: 票房 TOP10 }, xAxis: { type: value }, yAxis: { type: category, data: topData.names }, series: [{ type: bar, data: topData.values }] }); } initChart(); /script /body /html启动 Web 服务cd web python app.py浏览器访问http://localhost:5000如果能看到两个图表说明可视化链路是通的。10. 功能测试与效果验证系统开发完成后建议按下面步骤做一遍功能验证确保每个环节都能跑通。测试环节测试操作预期结果判断标准爬虫功能运行爬虫脚本采集首页数据生成 CSV 文件字段完整数据条数与页面显示符合数据清洗运行 clean_data.py清洗后的 CSV 无重复、无空票房重复行数为 0空值数量为 0HDFS 上传使用 hdfs dfs -put文件出现在指定 HDFS 路径ls 命令能看到文件Hive 建表在 Hive 执行建表语句表创建成功show tables 能看到 movie_boxofficeSpark 统计运行 Spark 脚本控制台输出统计结果结果与手动计算一致API 接口curl 请求 /api/daily返回 JSON 数组数据非空且格式正确可视化页面浏览器访问页面图表正常加载无 404无 JS 报错测试时可以选用小样本数据例如只爬取一天的数据先验证流程再扩展到全量数据。11. 资源占用与性能观察在运行 Hadoop 和 Spark 时需要关注物理内存和 CPU 占用。常见观察方式free -h # 查看内存 top # 查看 CPU 和进程 hdfs dfsadmin -report # 查看 HDFS 状态伪分布式环境下Hadoop 的 NameNode、DataNode、ResourceManager、NodeManager 会占用不少内存建议开发机至少有 16G 内存。如果内存不足可以关闭 YARN只保留 HDFSSpark 以 local 模式运行。Spark 任务的资源占用和以下因素有关读取的文件大小文件越大executor 需要的内存越多。分区数默认分区数会影响并行度。聚合操作groupBy、join会产生 shuffleshuffle 阶段耗内存。输出结果大小结果集过大时写出文件较慢。降低资源占用的方法包括使用coalesce()减少分区数。在读取 CSV 时只选择必要字段。分批次处理大文件避免一次性加载过大。关闭不必要的日志输出。数据量较小时完全可以采用单机 local 模式跑通全流程数据量达到千万级以上时再考虑分配到集群节点。12. 常见问题与排查方法问题现象可能原因排查方式解决方案Hadoop 启动后 NodeManager 进程消失内存不足配置不匹配查看 hadoop 日志调低 yarn.nodemanager.resource.memory-mb或关闭 YARNSpark 读取 HDFS 文件报 FileNotFound路径不对或权限不足hdfs dfs -ls 检查路径修改路径执行 hdfs dfs chmod -R 755Python 爬虫采集到空数据页面结构变化或请求被拦截打印 HTML 前 200 行更新解析规则增加 User-Agent、CookieSpark 提交任务提示 OutOfMemoryexecutor 内存不够查看 Spark UI 的 Storage Memory增加 spark.executor.memory或减少分区数Flask 页面显示空白接口跨域或 JS 报错打开浏览器 F12 查看 Console安装 Flask-CORS检查接口返回格式MySQL 连接失败密码错误或端口不通执行 mysql -u root -p 测试修改数据库连接配置开放端口HDFS 上传文件速度慢节点间网络延迟或副本数过多检查网络和副本数调低 dfs.replication或优化网络Spark 统计结果有 NaN原始数据中存在非法字符检查清洗日志在清洗阶段统一处理缺失值和字符型数字遇到问题时先看日志再定位到具体环节。不要在没查日志的情况下盲目修改代码。13. 最佳实践与使用建议以下几个建议可以显著提升开发效率先跑通最小闭环先用少量数据完成“爬虫 - 清洗 - Spark - 可视化”的最小闭环再逐步扩展功能。规范化目录把爬虫、清洗、分析、Web 代码分开避免所有代码堆在一个文件里。保留原始数据清洗前的原始数据不要覆盖方便回溯和对比。做好数据备份定期把 MySQL 和分析结果导出到备份目录防止误删。写清爽日志在爬虫和 Spark 脚本中加入打印信息记录处理条数和耗时。接口做参数校验Flask 接口提供 start_date、end_date 等参数方便前端筛选。控制爬虫频率一定不要高并发抓取目标网站优先使用官方 API 或二手公开数据集。涉及版权、隐私数据时必须确认授权。如果时间充足可以给系统增加几个亮点功能比如用户登录、浏览器端手动上传 CSV、定时任务自动爬取、导出 PDF 报告。这些都能丰富毕业设计的展示内容。14. 总结与下一步这个选题最值得尝试的地方在于它覆盖了大数据项目中最常用的 Python 爬虫、Hadoop 和 Spark 三个技术栈但每个环节都有成熟工具支撑不需要从零造轮子。最先应该验证的是“爬虫到 CSV”这一步因为后续所有流程都依赖数据质量。最容易踩的坑是 Hadoop 环境配置和 Spark 内存溢出建议在小数据量下调通流程后再上集群。后续可以继续扩展的方向包括使用 Hive 做更复杂的 SQL 分析使用 Kafka 做实时票房数据接入使用 Druid 或 ClickHouse 做高并发查询以及加入票房预测模型。先把基础链路搭好后面每个点都可以独立延伸。