ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

汽车销售分析系统:Python爬虫+Hadoop+Spark+Streamlit全链路实战

汽车销售分析系统:Python爬虫+Hadoop+Spark+Streamlit全链路实战 如果你正在为“汽车销售分析”类毕业设计选技术栈或者想做一个有“大数据味道”的课程项目却不知道该把 Python 爬虫、Hadoop、Spark、Streamlit 怎么串联起来那么这篇文章值得看完。先给一个明确判断这个项目真正的难点不是单点技术而是整条链路的贯通。爬虫抓下来数据怎么进 HDFSHDFS 里的原始数据怎么让 Spark 做清洗和聚合Spark 算出的结果怎么给 Streamlit 展示很多同学卡在“每个组件都能跑起来但放到一个项目里就不知道如何协作”。这篇文章就按这条链路完整拆开讲解并且给出可运行的代码示例和验证方式。另外要提前说明这类系统的完整形态应该是“爬虫采集 分布式存储 分布式计算 交互式可视化”。但在毕业设计或课程设计场景下你不需要真的搭一套大规模集群重点是让每个环节的职责清晰、流程能跑通、代码能解释清楚。所以本文采用 Hadoop 伪分布式 Spark 本地模式 Streamlit Web 应用的方案既保留了完整技术栈又能在单机上完成演示。1. 这个项目到底解决了什么问题汽车销售分析是数据分析类毕业设计里非常经典的方向。原因很简单业务场景明确数据字段容易理解分析结果也有实际业务含义。但很多初版方案只是“拿一张 Excel用 Pandas 算几个数再用 Matplotlib 画几张图”这样做不是不行而是技术层次不够答辩时很难讲出亮点。这套基于 Streamlit 的系统本质上解决的是三个问题。第一数据从哪来。用 Python 爬虫解决“没有数据”的尴尬。汽车销量、车型参数、价格区间、品牌排行这些信息在合法的公开渠道可以看到但手动复制显然不现实所以需要一个可复用的采集脚本。第二数据量大了之后怎么存储和计算。虽然单机用 Pandas 也能跑但为了体现大数据处理思路需要引入 HDFS 做分布式文件存储引入 Spark 做分布式内存计算。哪怕实际数据量不大这套设计在架构上已经具备横向扩展的潜力。第三分析结果怎么给非技术人员看。传统控制台输出和 Matplotlib 静态图不适合做成果展示。Streamlit 的价值在于用纯 Python 快速搭建交互式仪表盘支持下拉筛选、动态图表和实时刷新非常适合作为最终展示层。一个比较中肯的建议是如果你只想要“能交差”的项目上面任何一个部分都可以更简单但如果你想在技术报告和答辩中展示“系统工程能力”这套技术栈的组合会让项目有明显层次感。2. 系统总体架构与核心技术概念整个系统的数据流非常清晰按照“采集 → 存储 → 计算 → 展示”四个阶段划分每个阶段对应独立技术组件。建议用一张结构图记录在报告里文字描述如下。数据采集层负责从目标网站获取汽车销售相关的公开数据包括品牌销量、车型列表、价格区间、在售状态等信息。采集结果统一保存为 CSV 格式作为原始数据。这一层主要用到 Python 的 requests 和 BeautifulSoup 库。数据存储层采用 Hadoop HDFS。采集到的 CSV 文件上传到 HDFS 指定目录例如/car_sales/data。这样设计的好处是如果后续采集数据量增长HDFS 可以通过横向扩展存储节点来解决容量问题而不是在某台机器上不断加硬盘。数据处理层采用 Apache Spark。使用 PySpark 读取 HDFS 上的原始文件完成字段筛选、空值处理、格式转换、分组聚合等操作。最终把处理结果写回本地或者 HDFS 的output目录供展示层使用。数据展示层采用 Streamlit。通过 pandas 读取 Spark 处理后的结果文件利用 Streamlit 的交互组件构建筛选条件配合内建图表或 Plotly 展示趋势、排行和分布。用户无需了解底层数据逻辑就能通过浏览器操作整套分析系统。需要特别解释 Spark 和 Hadoop 的关系因为这是很多初学者最容易混淆的地方。Hadoop 的核心是 HDFS分布式文件系统和 MapReduce分布式计算框架而 Spark 是一个独立的内存计算框架它可以完全不依赖 Hadoop也可以读取 HDFS 上的数据作为数据源。在本项目中我们主要使用 HDFS 的存储能力计算部分用 Spark所以两者是协作关系不是替代关系。至于 Streamlit它的定位是“数据应用的快速开发框架”。与传统 Flask/Django 写 Web 页面不同Streamlit 不需要你写 HTML、CSS、JavaScript只要写 Python 脚本页面组件会随着脚本执行自动渲染。这对数据分析方向的学生非常友好。3. 环境准备与前置条件为了避免在环境上浪费太多时间建议在开始之前检查以下条件。操作系统建议使用 Ubuntu 20.04 或 CentOS 7 等 Linux 发行版Windows 用户建议先安装 WSL2 或者直接在虚拟机上操作因为 Hadoop 在 Windows 上的配置问题比较多。如果你的项目必须运行在 Windows 上也可以但需要额外处理 Hadoop 本地库和 winutils不建议新手一上来就挑战。Python 版本建议 3.8 以上推荐 3.9 或 3.10。Streamlit 和 PySpark 对 Python 版本有各自要求太新的 Python 版本有时会遇到依赖包尚未适配的情况所以不要一味追求最新版。需要提前安装的工具包括JDK 8 或 JDK 11Hadoop 运行依赖Hadoop建议使用 3.x 版本伪分布式模式即可Spark建议使用 3.x 版本需提前确认与 Hadoop 的兼容性Python 虚拟环境工具venv 或 condaGit可选用于版本管理这里不写死具体版本号因为 Hadoop、Spark、Python 三者之间存在版本兼容矩阵最稳妥的方式是先确认一组互相匹配的版本再开始安装。以实际项目环境为准本文重点演示通用思路。依赖安装命令可以统一在虚拟环境中执行。先创建虚拟环境python3 -m venv car_sales_env source car_sales_env/bin/activate然后安装 Python 库pip install streamlit pyspark pandas requests beautifulsoup4 plotly如果你的机器无法直连 PyPI可以配置国内镜像源但不建议在文章中讨论代理相关的敏感内容。可以提一句“如果下载速度慢可以配置国内 pip 镜像”这是很常规和安全的建议。检查安装是否成功streamlit version python -c from pyspark.sql import SparkSession; print(pyspark ok)如果这两个命令都能正常输出说明基础环境已经准备好了。4. 数据采集模块设计与实现在动手写爬虫之前必须先强调合规问题。爬虫只能采集公开合法、允许访问的数据且需要遵守目标网站的 robots 协议和访问频率要求不得通过绕过访问限制、破解验证码等非法手段获取数据。毕业设计项目更要注意这一点尽量选择提供公开数据接口或明确允许爬取的网站。如果目标网站没有公开接口也可以用模拟数据代替把爬虫设计成“数据来源示例”重点是展示爬虫技术能力而不是真正破坏某个网站的服务。从技术实现角度一个完整的汽车销售爬虫通常包含数据源分析、页面请求、HTML 解析、数据清洗、结果保存五个步骤。这里演示一个通用章节假设目标页面是一个展示汽车销量排行榜的公开页面每行包含品牌、车型、销量、价格区间等字段。用 requests 请求页面用 BeautifulSoup 定位表格行解析数据后输出为 CSV。# 文件路径spider/car_spider.py import csv import requests from bs4 import BeautifulSoup headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 } def fetch_page(url): 请求目标页面返回 HTML 文本 resp requests.get(url, headersheaders, timeout10) resp.encoding resp.apparent_encoding if resp.status_code 200: return resp.text else: raise Exception(f请求失败状态码{resp.status_code}) def parse_sales_table(html): 解析页面中的销量表格 soup BeautifulSoup(html, html.parser) table soup.find(table) rows [] if table is not None: for tr in table.find_all(tr)[1:]: cells tr.find_all(td) if len(cells) 4: brand cells[0].text.strip() model cells[1].text.strip() sales cells[2].text.strip().replace(,, ) price cells[3].text.strip() rows.append([brand, model, int(sales), price]) return rows def save_to_csv(rows, file_path): 保存为 CSV 文件 with open(file_path, w, newline, encodingutf-8-sig) as f: writer csv.writer(f) writer.writerow([brand, model, sales, price_range]) writer.writerows(rows) if __name__ __main__: target_url https://example.com/public_car_sales # 替换为实际合法数据源 html fetch_page(target_url) data parse_sales_table(html) save_to_csv(data, car_sales_raw.csv) print(f采集完成共 {len(data)} 条记录)这段代码的关键逻辑有三处。请求头里设置 User-Agent 是为了模拟正常浏览器访问降低被拒绝的概率解析时删除销量字段中的逗号是为了让字符串 “12,345” 能转成整数 12345保存时使用 utf-8-sig 编码是为了让生成的 CSV 在 Excel 中打开时中文不乱码。如果目标页面不是简单的静态表格而是通过 JavaScript 动态渲染那么 requests 直接请求拿不到有效内容。更稳妥的做法是使用 Playwright 或 Selenium 模拟浏览器行为或者在浏览器开发者工具中寻找 XHR 接口直接请求接口地址。对毕业设计而言优先推荐找公开接口运维成本低代码也更容易解释。如果由于各种原因没有合适的真实数据源建议生成一套符合业务逻辑的模拟数据。字段可以包括月份、品牌、车型、销量、指导价、地区等用 Python 的 random 库生成 5 万条记录然后导出 CSV。这种方式同样可以演示后续的存储和计算流程。5. Hadoop HDFS 存储环境与数据上传数据采集完成后接下来要解决“把数据放到分布式文件系统”的问题。这里使用 Hadoop 伪分布式模式即在一台机器上同时模拟 NameNode、DataNode、SecondaryNameNode 多个角色。虽然它并不是真正意义上的集群但能完整展现 HDFS 的文件上传、下载、目录管理等操作。启动 Hadoop 之前需要确认几个关键配置。core-site.xml 中的 fs.defaultFS 要指定为 hdfs://localhost:9000这样客户端才能通过这个地址访问 HDFS。hdfs-site.xml 中要根据机器内存设置副本数伪分布式环境下副本数建议为 1否则会因找不到足够的 DataNode 而一直处于 under-replicated 状态。格式化 NameNode 是首次启动必做的操作但要注意格式化操作会清空原有元数据所以只在初始化时执行一次不要在实验过程中随便重复执行。# 格式化 NameNode仅在首次初始化时执行 hdfs namenode -format格式化完成后启动 HDFS 服务start-dfs.sh使用 jps 命令检查进程是否就绪预期能看到 NameNode、DataNode、SecondaryNameNode 三个进程。如果缺少 DataNode先查看日志文件排查启动失败原因常见原因是目录权限问题或端口被占用。然后创建项目目录并上传爬虫生成的 CSV 文件# 创建 HDFS 目录 hdfs dfs -mkdir -p /car_sales/data hdfs dfs -mkdir -p /car_sales/output # 上传原始数据 hdfs dfs -put car_sales_raw.csv /car_sales/data/ # 查看文件是否上传成功 hdfs dfs -ls /car_sales/data/上传后可以尝试读取文件的前几行确认数据没有损坏hdfs dfs -cat /car_sales/data/car_sales_raw.csv | head -5这个阶段可能遇到的典型问题是执行 start-dfs.sh 时提示找不到命令。原因通常是 Hadoop 环境变量没有配置需要检查 ~/.bashrc 中的 HADOOP_HOME 和 PATH。另一个典型问题是 DataNode 无法启动这通常与第一次格式化后持久化目录冲突有关解决方式是在确保没有重要数据的前提下清空 tmp 目录后重新格式化但生产环境绝不能轻易这样做。到这里“采集数据 → 存入 HDFS”的链路已经完成。在毕业设计答辩时可以重点解释这一步的价值HDFS 提供了跨节点的文件存储能力原始数据进入 HDFS 后后续任何计算节点都可以按照统一路径读取而不需要关心数据具体存放在哪台机器上。6. 基于 Spark 的数据清洗与聚合分析数据进入 HDFS 后下一步是使用 Spark 进行分析计算。Spark 的优势在于它会在内存中完成多阶段计算比传统的磁盘读写式 MapReduce 更适合做迭代式分析和交互式查询。在毕业设计场景下我们可以用 PySpark 编写一个 ETL 任务从 HDFS 读取原始 CSV完成数据清洗再执行典型的聚合分析。分析任务可以围绕以下几个问题展开每个汽车品牌的月销量趋势如何哪些车型在总销量榜上排名靠前不同价格区间的销量分布有什么规律年度总销量 Top10 车型有哪些假设原始 CSV 包含 month、brand、model、sales、price_range 五个字段那么 Spark 代码可以这样写。# 文件路径analysis/sales_analysis.py from pyspark.sql import SparkSession from pyspark.sql.functions import col, sum, desc spark SparkSession.builder \ .appName(CarSalesAnalysis) \ .getOrCreate() # 从 HDFS 读取原始数据注意编码必须与写入时一致 df spark.read.csv( hdfs://localhost:9000/car_sales/data/car_sales_raw.csv, headerTrue, inferSchemaTrue, encodingutf-8 ) print( 原始数据 Schema ) df.printSchema() print( 总记录数 ) print(df.count()) # 清洗过滤销量为空或小于等于0的记录 df_clean df.filter(col(sales).isNotNull() (col(sales) 0)) # 聚合1各品牌总销量 brand_summary df_clean.groupBy(brand) \ .agg(sum(sales).alias(total_sales)) \ .orderBy(desc(total_sales)) print( 品牌销量 Top10 ) brand_summary.show(10) # 聚合2各价格区间销量分布 price_summary df_clean.groupBy(price_range) \ .agg(sum(sales).alias(total_sales)) \ .orderBy(desc(total_sales)) print( 价格区间销量分布 ) price_summary.show() # 写入处理结果供 Streamlit 展示使用 brand_summary.coalesce(1).write.csv( hdfs://localhost:9000/car_sales/output/brand_summary, headerTrue, modeoverwrite ) price_summary.coalesce(1).write.csv( hdfs://localhost:9000/car_sales/output/price_summary, headerTrue, modeoverwrite ) spark.stop()这段代码里有几个容易出错的地方需要留意。第一read.csv 的 encoding 参数必须与爬虫写入时的编码一致。如果爬虫写入是 utf-8-sigSpark 读取时指定 encodingutf-8 已经可以正常处理 BOM但若写入时是 gbk则要相应修改。第二write.csv 时使用 coalesce(1) 是为了将结果合并成单文件方便后续用 pandas 直接读取。如果不做合并Spark 会为每个分区生成一个 part 文件Streamlit 读取时就需要额外处理。对于展示型项目合并成单文件更省事。第三Spark 任务提交后输出非常长真正需要关注的是日志中最后显示的执行状态。如果出现 ERROR 或 Exception优先看最底部的错误摘要而不是滚动查看几千行 INFO 日志。运行 Spark 任务的命令spark-submit analysis/sales_analysis.py如果你的 Spark 与 Hadoop HDFS 不在同一台机器上需要把代码中的 hdfs://localhost:9000 换成实际的 NameNode 地址。如果只想在本地模式下测试也可以把读取路径改为本地 CSV 路径Spark 同样支持。运行完成后从 HDFS 拉取结果到本地hdfs dfs -getmerge /car_sales/output/brand_summary ./brand_summary.csv hdfs dfs -getmerge /car_sales/output/price_summary ./price_summary.csv这一步的意义是最终的 Streamlit 应用不需要依赖 Spark 环境只需要读取已经计算好的结果文件这对于毕业设计演示来说更加稳定也方便在没有 Hadoop 的机器上临时展示页面。7. Streamlit 交互式可视化大屏制作Streamlit 是整个系统的门面。前面所有环节都是数据准备最终用户看到的是浏览器里的仪表盘页面。Streamlit 的核心思路是“把 Python 脚本的每一次执行结果渲染成界面”页面上的组件会与脚本变量直接绑定用户触发控件时脚本会重新执行。本项目中的仪表盘至少应该包含四个模块核心指标卡片、品牌销量排行、月度销量趋势、价格区间分布。为了增强可视化效果可以引入 Plotly 绘制交互式图表Streamlit 本身也提供 st.line_chart、st.bar_chart 等简单图表接口但 Plotly 的图表更美观交互能力更强。先看整体页面骨架代码# 文件路径app/dashboard.py import pandas as pd import streamlit as st import plotly.express as px st.set_page_config( page_title国内汽车销售分析系统, page_icon:car:, layoutwide ) st.title(国内汽车销售分析系统) st.markdown(基于 Streamlit Spark Hadoop 的毕业设计项目示例) st.cache_data def load_data(): brand_df pd.read_csv(../output/brand_summary.csv) price_df pd.read_csv(../output/price_summary.csv) trend_df pd.read_csv(../output/trend_summary.csv) detail_df pd.read_csv(../data/car_sales_raw.csv) return brand_df, price_df, trend_df, detail_df brand_df, price_df, trend_df, detail_df load_data()使用 st.cache_data 装饰器是为了缓存数据加载结果避免每次页面交互都重新读取 CSV 文件。这是 Streamlit 性能优化的关键手段否则当数据文件几百兆时页面响应会明显变慢。接下来构建侧边栏筛选器。在真实分析场景中我们经常需要按品牌、价格区间筛选后再查看图表。Streamlit 的多选组件可以方便地实现这个功能st.sidebar.header(筛选条件) brand_options detail_df[brand].unique().tolist() selected_brands st.sidebar.multiselect(选择品牌, brand_options, defaultbrand_options[:5]) filtered_df detail_df[detail_df[brand].isin(selected_brands)]然后展示核心指标卡片col1, col2, col3, col4 st.columns(4) col1.metric(数据总记录数, f{len(detail_df):,}) col2.metric(品牌数量, f{detail_df[brand].nunique():,}) col3.metric(车型数量, f{detail_df[model].nunique():,}) col4.metric(总销量, f{filtered_df[sales].sum():,})st.columns 是 Streamlit 的布局组件可用于在一行中排列多个模块。st.metric 组件适合展示关键指标标题下方会显示数值也可以增加 delta 参数表示变化量。品牌销量排行可以绘制横向条形图fig_brand px.bar( brand_df.head(10), xtotal_sales, ybrand, orientationh, title品牌销量 Top10 ) fig_brand.update_layout(yaxisdict(autorangereversed)) st.plotly_chart(fig_brand, use_container_widthTrue)月度趋势图用折线图展示fig_trend px.line( trend_df, xmonth, ytotal_sales, colorbrand, title各品牌月度销量趋势 ) st.plotly_chart(fig_trend, use_container_widthTrue)价格区间分布用饼图或柱状图fig_price px.pie( price_df, namesprice_range, valuestotal_sales, title价格区间销量占比 ) st.plotly_chart(fig_price, use_container_widthTrue)最后展示明细数据表st.subheader(销售明细数据) st.dataframe(filtered_df, use_container_widthTrue)这里需要注意Streamlit 页面中每个图表模块都要通过 st.plotly_chart 或 st.dataframe 输出不能直接写 Python 表达式否则页面不会渲染任何内容。如果某个模块不需要展示可以直接注释掉不需要像传统 Web 开发一样配置路由。在展示层面还有一个常见需求如何把多个总结文件组织在一个页面里。建议按“总览 → 品牌排行 → 价格分布 → 趋势 → 明细”的顺序排列让用户在浏览时有清晰的信息层次。如果想让页面更专业可以增加标题、说明文字和分隔线但不要堆砌过多花哨组件保持仪表盘的清爽感。8. 完整启动流程与效果验证当代码都准备好后推荐先本地运行一次完整流程再把各步骤串联成脚本方便反复复现。建议的启动顺序如下启动 Hadoop HDFS 服务start-dfs.sh检查 HDFS 进程和数据文件jps hdfs dfs -ls /car_sales/data/运行 Spark 分析任务spark-submit analysis/sales_analysis.py从 HDFS 拉取结果到本地输出目录hdfs dfs -getmerge /car_sales/output/brand_summary ./output/brand_summary.csv hdfs dfs -getmerge /car_sales/output/price_summary ./output/price_summary.csv hdfs dfs -getmerge /car_sales/output/trend_summary ./output/trend_summary.csv启动 Streamlitstreamlit run dashboard.py启动成功后终端会显示本地访问地址默认是 http://localhost:8501。在浏览器中打开该地址可以看到仪表盘页面。如何验证系统正常可以从四个层面检查。数据层面仪表盘顶部的指标卡片应该显示正确的记录数如果总记录数与爬虫采集时打印的数量一致说明数据链路是通的。图表层面品牌销量排行图中条形图应该按销量从高到低排列价格区间饼图各扇区比例应该符合业务直觉例如“10-20万”区间通常占比最高。交互层面在侧边栏切换品牌筛选后总销量指标和明细数据表应该同步变化这说明组件绑定关系正确。日志层面终端中没有出现红色报错信息Streamlit 的页面访问日志会显示 200 状态码。如果你在浏览器中打开页面但没有看到图表优先检查输出 CSV 文件是否存在、列名是否与代码中的字段名一致。常见错误是 Spark 写出的文件列名带了双引号或特殊前缀导致 pandas 读取后字段对不上这时可以先打印 DataFrame 的列名列表再用 rename 方法调整。9. 常见问题与排查方法根据实际开发中经常遇到的问题整理成一张排查表可以放在项目 README 中。问题现象可能原因排查方式解决方案Hadoop 启动时找不到命令环境变量未配置echo $HADOOP_HOME 查看结果在 ~/.bashrc 中配置 Hadoop 路径DataNode 无法启动格式化目录不一致查看 Hadoop 日志清空临时目录后重新格式化生产环境谨慎操作Spark 读取中文乱码文件编码不一致检查原始 CSV 编码Spark read 时指定正确 encodingSpark 聚合结果被分区成多文件默认分区数大于1查看输出目录 part 文件使用 coalesce(1) 合并输出Streamlit 页面启动后无图表结果文件路径不对检查 pandas 读取路径调整路径为实际输出目录Streamlit 数据更新不及时缓存没有刷新点击浏览器刷新按钮关闭 st.cache_data 或使用清理缓存功能爬虫请求被拒绝User-Agent 或访问频率问题查看响应状态码设置合法请求头降低访问频率HDFS 存储空间不足文件副本或临时数据过多hdfs dfs -du -h / 查看空间清理无用文件调大 HDFS 容量这里需要特别提一下 st.cache_data 的坑。在开发阶段如果你修改了 CSV 文件内容页面可能仍然显示旧数据因为 Streamlit 默认会缓存函数结果。解决办法是在方法上临时不使用缓存装饰器或者在浏览器中点击 Streamlit 右上角的“Clear cache”按钮。调试完成后再加上缓存这是开发调试与正式运行的典型差异。另一个常见坑是文件路径问题。很多同学在 vscode 中直接运行 dashboard.py但当前工作目录与文件所在目录不一致导致相对路径找不到 CSV。稳妥的做法是在代码开头根据__file__动态计算绝对路径import os BASE_DIR os.path.dirname(os.path.abspath(__file__)) OUTPUT_DIR os.path.join(BASE_DIR, .., output)这样无论在哪个目录下启动 Streamlit都能正确定位文件。10. 工程化建议与毕业设计注意事项如果你希望这个项目不仅是“跑得通”还能在评阅和答辩中拿到更好的评价可以参考以下工程化建议。目录结构要清晰。建议按数据采集、分析计算、可视化展示、输出结果四类拆分明细目录。例如car-sales-analysis/ ├── spider/ │ └── car_spider.py ├── analysis/ │ └── sales_analysis.py ├── app/ │ └── dashboard.py ├── data/ │ └── car_sales_raw.csv ├── output/ │ ├── brand_summary.csv │ └── price_summary.csv ├── docs/ │ └── README.md └── requirements.txt这种结构的好处是每个模块的职责一目了然评阅老师打开项目就能快速定位代码。代码中要适当添加注释但不要每行都注释。建议在关键步骤上方写清楚“这一步做什么、为什么这样做”。注释不是解释语法而是解释设计意图比如“这里用 coalesce(1) 是为了让 Spark 输出单个文件方便 Streamlit 读取”就比“合并分区”更有信息量。安全与合规方面爬虫代码必须在 README 中注明数据来源声明“仅用于学习研究”并遵守目标网站规则。涉及 HDFS 操作时尽量使用普通用户权限不要用 root 直接启动所有服务。如果项目部署到服务器上Streamlit 服务需要增加访问控制最简单的方式是绑定回环地址或者使用内网部署不要默认暴露到公网。大数据量的场景下不要在 Streamlit 中直接加载全量明细数据。更合理的做法是让 Spark 完成所有聚合Streamlit 只读取聚合结果明细数据最多用于局部筛选浏览。这样可以减少内存压力也符合“计算层与展示层分离”的设计思想。关于论文和答辩阐述推荐把整个系统分成五个技术亮点来讲。第一基于爬虫的自动化数据采集解决了数据来源问题第二基于 HDFS 的分布式存储解决了原始数据统一管理问题第三基于 Spark 的高效分析计算解决了批量数据聚合问题第四基于 Streamlit 的交互式可视化解决了结果展示问题第五整条链路的技术选型具有扩展性后续可以接入更多数据源、增加算法模型、部署到集群环境。如果项目中还提到算法或模型可以补充一个预测模块。例如基于历史销量数据使用 Prophet 或 ARIMA 模型预测下月销量然后用 Streamlit 绘制预测曲线。这个扩展会进一步提升项目复杂度适合有余力的同学。最后提醒一句不要把 HDFS 格式化当成常规操作不要在未确认数据安全的情况下重复执行。毕业设计是学习过程也是培养工程习惯的过程安全边界、权限管理和数据备份意识比跑通代码更重要。
返回列表