ARTICLE DETAIL

资讯详情

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

基于Streamlit的汽车销售大数据分析与可视化系统

基于Streamlit的汽车销售大数据分析与可视化系统 基于Streamlit的国内汽车销售分析系统是一个很适合计算机毕业设计的综合选题它同时牵起Python爬虫、Hadoop/Spark大数据分析和Web可视化三条技术线。如果你正在找一类既能展示数据采集能力又能体现大数据处理思路还能直接给评委演示交互界面的项目这个方向比单纯做前端页面或者单纯跑一次算法要有说服力得多。这类项目的核心价值不是把某个图表做得好看而是把一条完整链路打通从公开网站抓取汽车销售相关数据经过清洗后存入HDFS或MySQL再用Spark做离线分析最后用Streamlit快速搭建一个可交互的销量分析平台。整个系统覆盖了数据获取、存储、计算、展示四个环节正好对应大数据开发岗位常见的工作流也容易在答辩时讲清楚。我建议先把系统边界想清楚不要一开始就同时上太多组件。下面按我实际跑过这类项目后的顺序从架构设计、数据采集、离线分析、可视化展示到踩坑记录完整拆一遍。1. 先搞清楚这个毕业设计要解决的真正问题1.1 它不是一个单一的Web应用而是一条数据链路很多人看到“分析系统”四个字第一反应是做一个漂亮的管理后台把几个静态表格放进页面。但实际上这个题目的难点在于数据从哪来、怎么存储计算、怎么让页面读分析结果。Streamlit只是最后一公里的展示层真正的功夫在前面。国内汽车销售分析需要回答几类问题某个月某个品牌卖了多少辆不同价格区间的销量分布如何哪个车型增长最快不同省份的市场份额有什么差异。要回答这些问题必须先有数据然后对数据做聚合计算。所以这个系统的核心是数据处理不是页面交互。适合把这个选题拿去做毕业设计的同学通常已经掌握Python基础了解过爬虫的基本写法但对Hadoop、Spark和Streamlit还没有完整的项目经验。做这个项目正好可以把这些零散知识点串起来。1.2 技术选型为什么偏偏是这几件套系统里最显眼的三个技术点是Python爬虫、HadoopSpark、Streamlit。这个组合不是随意的。Python爬虫负责数据采集选择Python是因为生态完善requests、BeautifulSoup、pandas都有成熟用法写起来代码量少学生容易掌握。Hadoop和Spark负责处理规模较大的数据毕业设计里不需要真的跑到多个节点但可以把单机环境搭起来用Spark读取HDFS上的文件做分布式计算演示。这样既体现大数据技术栈又不会把环境复杂度拉得太高。Streamlit则负责把分析结果变成Web页面它比Flask/Django简单很多不需要写HTML模板直接用Python写界面适合没有前端基础的同学。我见过不少人问能不能用Flask替代Streamlit。可以但Streamlit对数据展示的默认支持更好一个st.dataframe就能展示DataFrame一个st.line_chart就能画趋势图省去大量时间。1.3 整体架构和数据流向建议把整个系统分成四层采集层、存储层、计算层、展示层。采集层用Python爬虫把公开的汽车销量数据抓下来输出为文件或写入MySQL存储层可以先用HDFS保存原始数据同时用MySQL保存清洗后的结构化数据计算层用Spark读取数据完成聚合、排序、统计分析结果输出为CSV或表格展示层用Streamlit读取计算结果生成图表和筛选器。这样设计有一个明显好处每一层都可以单独测试。爬虫出问题单独改爬虫Spark任务出问题不考虑页面页面加载慢可以先查结果文件生成是否正常。答辩时也可以说系统采用了分层架构符合工程习惯。数据采集可以控制在一两万条到几十万条看目标网站的数据量和页面数量。不需要刻意追求大数据量关键是让Spark的分布式计算逻辑有存在的意义。如果只有几百条数据直接Excel也能做那就体现不出大数据分析了。2. 数据采集合规爬虫与数据清洗2.1 数据来源选择和合规边界采集对象要优先选有公开数据、页面结构稳定、访问速度有保障的网站。不建议去找需要登录、有强验证码、数据接口加密的平台否则大部分时间会耗在反爬对抗上偏离毕业设计主题。更稳妥的来源包括公开发布的年报页面、汽车行业统计站点、汽车垂直媒体公开榜单。也可以直接用一些统计网站导出的Excel或CSV作为补充数据。我一般会建议把“爬虫采集”和“公开数据集下载”结合一部分数据用爬虫抓取体现采集能力一部分用现成数据保证字段完整和数量充足。注意合规边界。只能抓取公开信息遵守目标网站的robots协议和服务条款控制请求频率不要大量并发请求不要抓取用户隐私数据。代码里要设置请求间隔比如sleep(1)。同时记录数据来源和时间让整个采集过程有据可查。2.2 爬虫写法的核心步骤写爬虫时我的做法是先确定目标页面结构再写解析逻辑。先用requests获取页面再用BeautifulSoup或lxml解析HTML。如果页面数据是JSON格式的可以直接用requests获取JSON后转成DataFrame会比解析HTML稳定得多。下面是一个通用示例表示从某个公开页面抓取表格数据实际字段需要根据目标页面调整import requests import pandas as pd from bs4 import BeautifulSoup import time headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) } url https://example.com/car-sales resp requests.get(url, headersheaders, timeout10) resp.encoding utf-8 soup BeautifulSoup(resp.text, html.parser) rows [] for tr in soup.select(table tr): cells [td.get_text(stripTrue) for td in tr.select(td, th)] if cells: rows.append(cells) df pd.DataFrame(rows) df.to_csv(car_sales_raw.csv, indexFalse, encodingutf-8-sig) time.sleep(1)注意设置resp.encoding很多中文页面可能返回gbk编码不设置会出现乱码。写入CSV时用utf-8-sigExcel打开才不容易乱码。抓完数据后先不要急着分析先打印df.head()和df.info()确认字段数量、类型和空值情况。这一步能省下后面大量排查时间。2.3 数据清洗和字段设计汽车销量数据常见的字段包括日期、品牌、车型、销量、厂商、地区、价格区间、能源类型等。不同网站字段差异很大建议先统一设计一张表或一个CSV的字段结构。清洗时重点处理缺失值、重复记录、数据格式不一致。比如日期字段可能是“2024-01”或“2024年1月”需要统一成“2024-01”。销量字段可能是“12,345”需要去掉逗号转成整数。品牌名称可能有的写“上汽大众”有的写“大众”也要根据分析需求规范化。我用pandas做清洗比较顺手大致流程是读取原始数据去重补缺失改类型重命名列保存为清洗后的文件。如果采集的数据有几十万条可以先用pandas处理子集熟悉流程后再用Spark处理全量。3. 存储与离线分析Hadoop/HDFS 加 Spark 怎么落地3.1 存储方案不要一上来就上HDFS如果你的电脑配置一般不想折腾虚拟机可以先让整个项目跑在本地文件系统最后再决定是否把数据放到HDFS。很多同学在环境上卡太久其实可以先跑通功能再升级存储。推荐两种方案。方案A本地文件 MySQL。爬虫把数据写入本地CSV清洗后导入MySQLSpark直接读MySQL或读取CSV。方案B本地Hadoop伪分布式 HDFS。启动NameNode和DataNode命令行put文件到HDFSSpark用路径读取hdfs:///user/...。方案B更能体现大数据技术栈但环境配置时间会长一些。如果你要使用HDFS先确认Hadoop版本和Java版本匹配然后启动HDFS。启动后用hdfs dfs -mkdir -p /car_sales/data创建目录再上传文件。我建议用命令行验证文件确实上传成功再写Spark代码。3.2 Spark分析任务怎么组织Spark分析的核心是把数据读进来转换成DataFrame然后用类似SQL的操作做聚合。不管数据在CSV、MySQL还是HDFSSpark都能读。建议先用本地模式调试代码跑通后再把读取路径切到HDFS。用Spark读取CSV的示例from pyspark.sql import SparkSession spark SparkSession.builder.appName(CarSalesAnalysis).getOrCreate() df spark.read.csv(car_sales_clean.csv, headerTrue, inferSchemaTrue) df.createOrReplaceTempView(car_sales) result spark.sql( SELECT brand, SUM(sales) AS total_sales FROM car_sales GROUP BY brand ORDER BY total_sales DESC ) result.show() result.write.csv(spark_result/brand_sales, headerTrue, modeoverwrite)这段代码体现了完整步骤创建SparkSession读取数据建临时视图写SQL输出结果。毕业设计答辩时可以用这段代码说明自己理解Spark的DataFrame和临时视图机制而不是只调用一次count()。注意输出目录不要提前存在否则会报错。也可以设置modeoverwrite但Spark写CSV时会生成多个part文件这是正常现象。Streamlit读取时最好读取整个目录下的文件拼接或者先转换成一个汇总文件。3.3 哪些分析指标和算法值得放进系统汽车销售分析最需要的是描述性统计和对比分析。推荐做以下指标月度销量趋势判断市场整体走势品牌销量Top10看头部品牌集中度车型销量排名找热销车型价格区间分布看消费升级或降级趋势地区销量占比看区域差异同比环比变化看增长情况算法部分不需要太复杂。可以加一个简单的KMeans聚类对车型按销量增长率、市场份额做分类分出“热门车型”“潜力车型”“边缘车型”。也可以用线性回归对下一个季度销量做一个简单预测。这些算法用Spark MLlib能实现代码量不大但能说明项目不是只有SQL统计。不过要控制算法数量毕业设计有一个核心算法展示就够了。不要同时堆五六个算法这样反而讲不清楚。4. Streamlit 可视化交互系统4.1 页面结构和组件设计Streamlit的页面结构可以围绕“筛选条件 指标卡片 图表 数据表格”来规划。一个典型的分析页面包含侧边栏和主区域。侧边栏放品牌选择、月份范围、地区筛选主区域放总销量、销量趋势图、品牌排名图、车型表格。页面不要太复杂否则运行时候交互响应会变慢。我一般用三个页面首页总览总销量、月度趋势、品牌Top10品牌分析按品牌看车型销量、价格分布、增长趋势区域分析按地区看销量分布Streamlit有页面切换组件可以用st.sidebar.radio选择页面也可以用st.page_link。推荐用radio简单直观。4.2 图表展示和筛选器实现Streamlit本身支持line_chart、bar_chart但样式相对简单。想要更贴近报告展示效果可以用plotly生成图表再通过st.plotly_chart显示。用pandas做筛选用plotly做图形两者搭配很顺手。示例import streamlit as st import pandas as pd import plotly.express as px df pd.read_csv(spark_result/brand_sales.csv) brands st.sidebar.multiselect(选择品牌, df[brand].unique()) if brands: df df[df[brand].isin(brands)] fig px.bar(df, xbrand, ytotal_sales, title品牌销量) st.plotly_chart(fig) st.dataframe(df)这个示例虽然简单已经包含“读取结果文件”“侧边栏筛选”“生成图表”“展示表格”四个Step。这里要提醒Streamlit每次交互都会从上到下重新执行脚本如果结果文件很大每次重新读取很慢。可以先用st.cache_data装饰器缓存数据读取函数减少重复读取。st.cache_data def load_data(path): return pd.read_csv(path)这样前端切筛选条件时只会重新处理数据不会每次都读磁盘。4.3 手动更新数据与自动刷新爬虫采集数据不是一次性的系统最好支持手动更新。我建议在侧边栏加一个“更新数据”按钮点击后执行爬虫脚本和Spark分析脚本再刷新页面。Streamlit里可以用st.button在按钮回调里调用subprocess或直接调用Python函数。if st.button(更新数据): import subprocess subprocess.run([python, crawler/car_sales_crawler.py]) subprocess.run([spark-submit, analysis/run_analysis.py]) st.success(更新完成)这里要注意Spark任务时间比较长Streamlit页面会等待脚本执行结束。简单演示没问题但不适合多次点击。如果要按时长控制可以改为手动在终端运行后台任务页面只负责展示结果。5. 项目目录、运行流程和关键代码示例5.1 推荐目录结构我建议把项目按功能分目录方便答辩时展示。一个常见的目录结构如下car_sales_system/ ├── crawler/ │ └── car_sales_crawler.py ├── data/ │ ├── raw/ │ └── clean/ ├── analysis/ │ ├── run_analysis.py │ └── spark_utils.py ├── app/ │ ├── main.py │ └── pages/ ├── requirements.txt └── README.md其中crawler放爬虫脚本data放原始数据和清洗数据analysis放Spark分析代码app放Streamlit入口。README里写清楚环境安装、启动步骤、数据来源和系统架构毕业设计文档直接可以参考这个结构写。5.2 启动顺序和配置项整个系统的启动顺序建议是安装Python依赖运行爬虫脚本生成原始数据运行数据清洗脚本生成清洗数据启动Hadoop HDFS上传数据运行Spark分析脚本生成结果文件启动Streamlit读取结果文件展示如果不想在每一步都手动跑也可以写一个run_all.py脚本按顺序调用。但答辩演示时最好分步骤控制避免一次跑太久。依赖安装可以写进requirements.txtstreamlit pandas matplotlib plotly requests beautifulsoup4 pyspark具体版本号建议以实际环境为准安装时可以用pip install -r requirements.txt。5.3 最小可运行示例如果你的时间紧张可以先做一个最小可运行版本不启动Hadoop不写Spark先写一个Streamlit页面读取本地CSV展示。等页面跑通后再逐步加入Spark分析和HDFS存储。这种方式能快速看到效果避免一开始被环境问题打击。最小版本的Streamlit代码在前面已经出现过。要启动它在项目根目录运行pip install streamlit pandas plotly streamlit run app/main.py浏览器打开生成的本地地址如果能看到图表和表格说明Streamlit通路正常。之后再把数据读取替换成Spark输出文件把启动流程补完整。6. 实测踩坑记录环境、依赖和参数问题排查6.1 爬虫阶段常见问题爬虫最容易出现三类问题编码乱码、请求超时、解析结果为空。编码乱码一般是页面字符集和requests解析不一致导致。解决方法是先查看resp.apparent_encoding再设置resp.encoding。请求超时基本是网络或目标网站限流。可以在requests.get里设置timeout并且加异常捕获。如果连续请求失败先降低频率不要继续增大并发。解析结果为空先检查是不是页面结构变了或者需要动态渲染。很多页面的数据是JavaScript动态加载的直接requests拿到的HTML没有表格。这种情况可以用Selenium或Playwright但会增加环境复杂度。我更建议换一个数据源或者找页面的XHR接口直接获取JSON。6.2 数据处理和Hadoop/Spark阶段常见问题Spark环境的问题最常出现在版本和内存上。首先是Java版本和Hadoop版本不匹配导致NameNode启动失败。安装前先查清楚Hadoop对应的Java版本不要直接装最新版。其次是Spark读取HDFS文件时权限不足。可以检查当前用户是否有hdfs目录权限或者用hdfs dfs -chmod -R 755 /car_sales修改权限。第三个常见问题是OOM。Spark本地模式默认使用的内存可能不够可以在spark-submit里指定spark-submit --master local[*] --executor-memory 2g --driver-memory 2g analysis/run_analysis.py如果数据量不是特别大也可以把inferSchema设置为false手动指定字段类型减少推断开销。6.3 Streamlit页面阶段常见问题Streamlit最常见的问题是端口被占用。启动时报错可以换一个端口streamlit run app/main.py --server.port 8601图表中文乱码是另一个高频问题。matplotlib默认字体不支持中文需要配置中文字体。plotly一般没有这个问题所以推荐优先用plotly。还有缓存问题。如果更新了CSV文件但Streamlit页面还是显示旧数据是因为st.cache_data缓存了之前的读取结果。可以加一个参数或者点击“更新数据”后调用st.cache_data.clear()清理缓存。下面是几个常见问题的快速排查表按“先看现象再看原因”的顺序整理。现象优先排查方向常见处理办法爬虫结果乱码页面编码resp.encoding改为apparent_encoding或gbk解析结果为空页面结构和数据加载方式换静态页面或找XHR接口Spark任务OOM内存参数降低分区数增大executor-memoryNameNode起不来Java和Hadoop版本统一版本查看日志Streamlit端口冲突端口占用换--server.port端口页面数据不更新st.cache_data缓存st.cache_data.clear()7. 毕业设计答辩与项目验收怎么讲清楚、怎么演示7.1 演示流程设计答辩演示时间一般5到10分钟不要从爬虫代码开始讲要从业务问题开始。我的建议流程是先讲背景说明国内汽车销售分析对车企、消费者和研究者的意义。然后讲系统架构用一张图说明数据从哪来、怎么存储、怎么分析、怎么展示。接着现场演示页面筛选不同品牌看趋势图和Top10变化。最后展示代码结构重点说明Spark分析任务和Streamlit的缓存机制。整个过程要突出三个关键词数据采集、大数据分析、可视化。不要让评委觉得你只做了一个模板网站。7.2 答辩重点和可能被问的问题评委很容易问数据量有多大如果不大的话为什么要用Hadoop/Spark这个问题要提前准备。可以回答系统的核心是完整的大数据处理流程Spark部分可以在数据量增大时横向扩展单机环境下用Spark跑通说明掌握了分布式计算的开发方式。这样回答比较合理。还可能问爬虫抓来的数据是否合法需要说明只使用了公开数据、遵守网站规则、控制请求频率、仅用于学习和研究。还可能问Streamlit和传统前后端开发有什么区别可以回答Streamlit适合数据应用快速原型底层仍然是Python服务适合这个项目快速交付。7.3 后续扩展方向如果答辩后还有时间可以扩展几个方向接入实时数据流比如Kafka把Spark结果存入ClickHouse增加查询速度加入用户登录和权限控制用Docker打包整个环境方便部署。扩展方向不用全部实现但能体现你对项目的理解还没有停在表面。写在论文的“未来展望”部分是一个加分项。最后说一句我自己的体会这个项目真正落地时最该盯住的不是某个算法有没有调优而是每条数据从采集到展示要经过哪些环节每个环节的输入输出是否明确。把链路理顺了技术点自然就能串起来。答辩时也不会因为一个细节卡住就问倒你。
返回列表