ARTICLE DETAIL

资讯详情

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

Python数据分析可视化系统实战:Django结合爬虫与ECharts全流程解析

Python数据分析可视化系统实战:Django结合爬虫与ECharts全流程解析 简介基于Python的商品销售数据分析可视化系统源码采用Django框架开发内置数据爬虫模块面向计算机相关专业毕业设计或数据分析入门者可解决商品数据采集、清洗、入库、统计分析与可视化展示的完整流程需求。压缩包共1480个文件整体约17.68MB其中JS与CSS文件负责前端页面交互和界面样式PNG/JPG等图片提供可视化图表与页面素材Python源码为后端核心逻辑另有字体、地图等静态资源配置。已有181人学习使用源码经本地编译可运行配置好Python及Django环境即可启动。内容包含完整项目源码、前端组件库、爬虫脚本与配套资源目录结构清晰便于快速定位模块。既可直接用于课程设计或毕业设计答辩也可作为二次开发与学习Django数据分析项目的基础工程。1. 商品销售数据分析可视化系统Django 与爬虫的实战组合做毕业设计选型时Python Django 爬虫 可视化这套组合出现的频率极高原因很直接爬虫解决“数据从哪来”Django 解决“系统怎么搭”可视化解决“结果怎么展示”一条链路下来正好覆盖数据分析的完整流程。这套基于 Python 的商品销售数据分析可视化系统就是把上述链路做成了可直接运行的源码包核心功能包括商品数据采集、数据清洗入库、销售指标分析、可视化大屏展示。对于正在准备毕业设计、需要演示完整数据流转过程的同学来说这套系统的价值在于不仅能跑通而且每一层都有对应的代码可以讲解。适合的读者是学过 Python 基础、想用 Django 完成一个完整项目、又不想从零开始搭框架的从业者或学生。这篇笔记会从系统结构、爬虫链路、分析逻辑、可视化实现到环境配置逐层拆解最后集中讲本地跑起来的常见坑。2. 系统结构拆解Django 项目里的每一层都在干什么拿到源码包之后第一件事不是急着运行而是先看清目录结构。这套系统的核心是 Django 框架但和典型的“只能增删改查”的 Django 管理系统不同它加入了数据采集模块和数据分析模块所以在结构上天然分成几个职责不同的层次。2.1 从文件清单反推系统职能源码包里有一批前端资源文件比如 ZeroClipboard.swf 和 ZeroClipboard.as、ace.min.css、webarch 系列样式文件。ZeroClipboard 是一个经典的剪贴板复制组件ace.min.css 是代码编辑器 Ace 的样式文件webarch 则是一套后台管理界面主题。从这里可以判断系统的后台管理界面用了一套现成的 admin 主题并且带有在线编辑和复制功能。这些细节在跑通项目后会和前端页面一一对应提前了解它们的作用在排错时能更快判断是后端问题还是前端资源加载问题。整个项目的核心目录逻辑大概是这样的目录/文件职责manage.pyDjango 项目入口启动服务、执行迁移都靠它项目配置目录settings.py、urls.py负责路由注册和环境配置app 目录核心业务代码包含 models、views、爬虫脚本、分析脚本templatesDjango 模板文件前端页面结构static静态资源包括 webarch 主题、css、js、图片数据文件目录爬虫采集后的原始数据通常为 csv 或 json这个结构和大多数 Django 毕设项目的标准布局一致。需要注意的一点是这套系统不是纯后端渲染的它有一部分页面依赖前端框架做数据展示所以 static 目录的完整性直接决定了页面能不能正常显示。2.2 数据链路的起点爬虫采集模块爬虫模块是整个系统的数据源头没有这一层后面的分析可视化都是空谈。采集的典型流程是requests 发起请求获取 HTML 或 JSONBeautifulSoup 或正则解析目标字段清洗后存入 MySQL 或写入本地文件再由 Django 的数据层读取。一个常见的采集脚本结构如下import requests from bs4 import BeautifulSoup import json import time headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36, Accept: text/html,application/xhtmlxml,application/xml;q0.9,image/webp,*/*;q0.8 } session requests.Session() session.headers.update(headers) def fetch_goods_page(url): try: resp session.get(url, timeout10) resp.raise_for_status() resp.encoding resp.apparent_encoding return resp.text except requests.RequestException as e: print(f请求失败: {e}) return None def parse_goods_items(html): soup BeautifulSoup(html, html.parser) items [] # 注意不同电商页面的选择器差别很大需要按实际页面结构调整 for card in soup.select(.goods-item): item { name: card.select_one(.goods-name).text.strip(), price: card.select_one(.goods-price).text.replace(¥, ).strip(), sales: card.select_one(.goods-sales).text.strip(), shop_name: card.select_one(.shop-name).text.strip() } items.append(item) return items这段代码里最关键的是 session 复用和 timeout 设置。session 复用可以避免每次请求都重新建立 TCP 连接在采集多页数据时效率提升明显。timeout 设置也很重要没有 timeout 的 requests 请求在目标网站响应缓慢时会一直阻塞导致整个采集脚本卡死。resp.encoding 的强制指定也是一行值得注意的代码很多网页的 header 里没有正确声明编码不手动处理的话中文会乱码。常见做法是先用 resp.apparent_encoding 自动探测再合并手动指定。数据采集完成后需要存库这里有个容易忽略的问题爬虫抓下来的价格是字符串可能带各种符号或空格销量也可能是“5万”这类非标准格式。常见的做法是在 Item 阶段就完成基础清洗再交给 Django ORM 或直接写成 CSV。对于毕设项目来说直接把清洗后的数据写入 MySQL 比写 CSV 再导入更稳妥因为能在答辩时演示完整的数据流而不是只展示静态文件。3. 数据分析层怎么做价格带、销量榜与聚合指标的计算逻辑数据采集只是第一步“分析”才是这套系统的核心卖点。很多初学者拿到数据后直接拿去做图表忽略了分析逻辑的构建。这套系统的分析模块主要围绕商品销售场景展开典型分析包括价格分布、销量排行、店铺聚合、品类占比等维度。3.1 基于 Pandas 的商品指标计算与聚合分析层最常见的做法是用 Pandas 进行数据加工。Pandas 的 DataFrame 结构非常适合处理表格型商品数据分组的语法简洁聚合函数的表达力也强。以下是一段在 Django 视图之外独立运行的数据分析脚本它读取清洗后的 CSV计算价格带分布和销量 Top 榜import pandas as pd import numpy as np df pd.read_csv(goods_data.csv) # 清洗价格列转数值类型销量中的万处理成实际数值 df[price] pd.to_numeric(df[price], errorscoerce) df[sales] df[sales].astype(str).str.replace(万, 0000, regexFalse) df[sales] pd.to_numeric(df[sales], errorscoerce) # 剔除异常值价格为负或销量为空的记录直接丢掉 df df[(df[price] 0) (df[sales].notna())] # 价格带分箱0-5050-100100-200200以上 bins [0, 50, 100, 200, np.inf] labels [0-50, 50-100, 100-200, 200以上] df[price_band] pd.cut(df[price], binsbins, labelslabels, rightFalse) # 聚合统计每个价格带的商品数量和平均销量 band_stats df.groupby(price_band, observedFalse).agg( goods_count(name, count), avg_sales(sales, mean) ).reset_index() # 销量Top10商品 top10 df.nlargest(10, sales)[[name, price, sales, shop_name]] print(band_stats) print(top10)这段代码里有几个细节容易被忽视但实际影响分析结果。pd.to_numeric 的 errorscoerce 会把无法转换的值变成 NaN这样单价字段里混入的字母或空格不会导致整个脚本崩溃。销量里的“万”如果不处理排序时会出现“5万”大于“12000”但被当成字符串比较的荒诞结果。价格分箱的 pd.cut 需要指定 rightFalse否则默认是左开右闭会和你定义的标签边界不一致。数据清洗在这里起到了关键作用。实际采集到的数据不会像教科书里那么干净缺字段、格式错位甚至错行都很常见。对于毕设答辩来说讲清楚清洗规则比展示清洗结果更有说服力——评委想看到的是你理解了数据质量问题的常见来源而不只是把图表画出来。3.2 分析结果如何接入 Django 视图分析脚本跑完结果需要被 Django 视图读取并传递给前端。这里有两种实现路径一种是在 Django 视图中直接调用 Pandas 处理 ORM 查询出的数据另一种是预先将分析结果落库或用 JSON 缓存视图只负责读取。对于这套系统来说推荐第二种路径理由是响应速度更快、逻辑更清晰。一般来说分析结果可以先存成 JSON 文件Django 视图读取后在模板中渲染。示例代码如下import json from django.shortcuts import render def dashboard(request): with open(analysis_results_api.json, r, encodingutf-8) as f: data json.load(f) context { band_stats: data[band_stats], top10: data[top10], total_goods: data[total_goods], } return render(request, dashboard.html, context)为什么不在视图里现算一方面是因为 Pandas 启动和数据加载本身有开销每次刷新页面都重新算一遍体验会变差另一方面是因为毕设场景下分析脚本作为独立模块存在答辩时可以单独演示这比黑匣子式的“页面出数字”体感要好很多。如果项目里用到了 Django Rest Framework 提供接口那 JSON 文件的缓存策略同样适用只需要把 context 替换成 JsonResponse 返回即可。4. 可视化如何不翻车ECharts 接入 Django 模板的正确姿势可视化层是这套系统最直观的展示面。选题阶段搜索“可视化大屏”得到的案例很多但大部分只展示了前端效果很少讲清楚数据是怎么从 Django 传到图表里的。在这套系统里可视化采用前后端分离渲染的方式Django 负责提供数据前端 ECharts 负责画图。4.1 从 Django 视图到 ECharts 的数据传递链路最直接的方式是在 Django 模板中把分析结果输出为 JavaScript 变量。这个做法虽然不是最优雅的但在毕设项目的复杂度下它足够直观、足够好排查。以下是典型的传递链路。视图侧返回数据后模板中做如下处理script var bandStats {{ band_stats|safe }}; var top10 {{ top10|safe }}; /script这里有两个注意点。第一|safe 过滤器必须加否则 Django 模板引擎会把 JSON 字符串里的引号转义成 HTML 实体导致 JavaScript 解析失败。这是模板渲染里最典型的一个坑而且报错方式非常迷惑——浏览器控制台报 SyntaxError但页面源码看起来完全正常。第二传给前端的数据必须是 JSON 兼容的结构如果数据里有 datetime 类型需要先在视图里转换成字符串否则 JSON 序列化会直接报错。图表初始化的部分以价格带分布柱状图和商品销量 Top10 条形图为例var bandChart echarts.init(document.getElementById(band_chart)); bandChart.setOption({ title: { text: 商品价格带分布, left: center }, tooltip: { trigger: axis }, xAxis: { type: category, data: bandStats.map(function(d) { return d.price_band; }) }, yAxis: { type: value }, series: [{ type: bar, data: bandStats.map(function(d) { return d.goods_count; }), itemStyle: { color: #409EFF } }] }); var topChart echarts.init(document.getElementById(top_chart)); topChart.setOption({ title: { text: 商品销量 Top10, left: center }, tooltip: { trigger: axis }, grid: { left: 3%, right: 10%, bottom: 3% }, xAxis: { type: value }, yAxis: { type: category, data: top10.map(function(d) { return d.name; }) }, series: [{ type: bar, data: top10.map(function(d) { return d.sales; }), itemStyle: { color: #67C23A } }] });这段代码里yAxis 的 data 用了商品名称如果商品名称太长图表会拉得很扁常见做法是加一个 formatter 截断字符串。另外 ECharts 图表在容器初始化时如果容器宽度为 0图表会渲染异常这在 tab 切换或折叠面板场景中非常常见。系统的 webarch 主题里如果有折叠菜单需要在菜单展开后手动调用 chart.resize()。4.2 静态资源配置与加载顺序问题可视化页面跑不起来很多时候不是代码逻辑的问题而是静态资源没有正确加载。Django 在开发模式下处理静态资源依赖 settings.py 里的静态文件配置。常见配置如下# settings.py STATIC_URL /static/ STATICFILES_DIRS [ BASE_DIR / static, ] STATIC_ROOT BASE_DIR / staticfiles跑开发服务器时用的是 STATICFILES_DIRS 指向的目录部署时用 collectstatic 收集到 STATIC_ROOT。这套系统里ECharts 的库文件一般放在 static 目录下的 js 文件夹中。模板里必须保证在引用页面脚本之前加载 ECharts 库。曾经遇到过页面报“echarts is not defined”检查后在项目里发现原因是 ECharts 的 script 标签写在了业务脚本之后浏览器按顺序解析时业务脚本先执行此时 echarts 还没有被挂载到全局作用域。这类问题靠浏览器开发者工具 Network 面板能迅速定位。另外需要留意 ECharts 的版本差异。老版本项目里页面可能使用 require.js 或 sea.js 做模块化加载但新版本 ECharts 已经全面转向 npm 包和普通 script 引用如果混用两种加载方式很容易出现全局变量污染。遇到这种情况最省事的做法是统一用 script 标签直接引入完整构建版的 echarts.min.js不需要动态按需加载的复杂配置。5. 本地跑起来的所有坑环境版本、MySQL 编码、静态文件 404拿到源码之后成败几乎完全取决于环境配置。很多时候项目代码没有任何问题但环境版本不匹配导致一连串跑不起来的翻车现场。下面这些坑是这套基于 Python 的商品销售数据分析可视化系统里最常踩的每一条都是真实经历。坑一Python 版本不匹配Django 直接无法启动现象在终端执行python manage.py runserver环境就报找不到某些模块或者提示 Django 版本不支持当前 Python 版本。原因项目使用的 Django 是旧版本时在 Python 3.10 环境下会暴露兼容性问题。例如 Django 2.x 在 Python 3.7 环境下运行稳定但 Python 3.9 会报AttributeError: module os has no attribute sep之类的错误——其实根源是内置模块路径变化导致的。解决先看源码里是否有 requirements.txt确认里面标注的 Django 版本再创建对应版本的虚拟环境。常见的做法是安装 Python 3.6 或 3.7然后pip install django2.2。如果新项目里不需要兼容老代码直接升到 Django 4.x 并修改 settings 里的配置也行但改代码的工程量远大于装一个旧版本 Python血泪经验是毕设项目追求稳定不追求新版本。坑二MySQL 无法连接报错Access denied for user rootlocalhost现象Django 项目启动后访问首页页面报数据库连接错误密码明明正确却连着失败。原因MySQL 8.x 默认的认证插件是 caching_sha2_password而旧版 mysqlclient 或 PyMySQL 版本不支持导致即使密码正确也无法连接。解决有两种路径建议先用简单方案在 MySQL 里执行下面的命令把 root 用户的认证方式改为 mysql_native_passwordALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY 你的密码; FLUSH PRIVILEGES;如果不想动数据库配置就换 pip 包版本把 mysqlclient 升级到 2.x 以上或者安装新版 PyMySQL。个人习惯是优先引入新版 PyMySQL然后在 Django 项目的__init__.py里加入以下代码import pymysql pymysql.install_as_MySQLdb()这两种方式都值得了解因为答辩时如果换了一台电脑演示环境差异可能导致其中一种失效。坑三静态文件全部 404页面样式和图表全部丢失现象项目能跑起来页面结构也有但 css/js 全部加载失败控制台全是红色 404。原因settings.py 里 DEBUG 模式设置为 False 时Django 的 runserver 不会自动提供静态文件服务。这是开发部署中最高频的坑之一。解决开发调试阶段把 DEBUG 设置回 True 是最快的如果项目涉及前端资源加载逻辑需要确认项目中 static 路径下的目录结构是否和模板中引用的路径一致。一个容易忽略的细节是STATICFILES_DIRS 路径写错一个字母就会导致所有文件找不到。优先用浏览器 Network 面板检查 404 链接的具体 URL和实际文件路径做对比这才是排查效率最高的方式。坑四网页显示乱码中文全部变成问号或菱形符号现象页面正常显示但数据库中的商品名称和店铺名称在页面上全是乱码或者爬虫采集到的 JSON 文件打开就是乱码。原因数据库连接字符集不是 UTF-8或者写入数据时没有统一编码。MySQL 5.7 及以下版本默认字符集是 latin1而 Django 写入的数据是 UTF-8两者不一致就会乱码。解决执行迁移前先检查 MySQL 库的默认字符集在创建数据库时指定 utf8mb4CREATE DATABASE goods_sales CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;同时在 Django 的 settings.py 数据库配置中加入 OPTIONS 指定编码方式DATABASES { default: { ENGINE: django.db.backends.mysql, NAME: goods_sales, USER: root, PASSWORD: 你的密码, HOST: 127.0.0.1, PORT: 3306, OPTIONS: {charset: utf8mb4}, } }注意一点utf8mb4 和 utf8 在 MySQL 里不是同一种东西utf8mb4 才能完整支持中文和 emoji 字符。数据量不大时完全不用考虑性能差异直接用 utf8mb4 就好。坑五ECharts 图表渲染空白但控制台没有错误现象图表容器显示了边框和背景但图表内容一片空白鼠标移上去能看到 tooltip。原因容器高度为 0。很多情况下DIV 容器的 CSS 没有显式设置高度ECharts 初始化时拿到的高度是 0渲染自然失败。这通常和 webarch 主题的 CSS 冲突有关。解决在 CSS 里给图表容器设置固定高度。这里有个不用来回改 CSS 的方案在初始化之前用 JavaScript 动态设置高度改动量最小不干扰全局样式var container document.getElementById(band_chart); container.style.height 400px; var bandChart echarts.init(container);如果容器本身存在于隐藏的 tab 页中还需要在切换到该 tab 后刷新图表具体做法是给下拉菜单的点击事件绑定一个chart.resize()调用。否则切换回来时会发现图表仍然是空白的这个不用惊慌属于 ECharts 生命周期管理中的经典偏差。以上五个坑覆盖了“环境版本-数据库连接-静态资源-字符编码-前端图表”这几个最容易翻车的环节把这五条对照着源码和本地环境跑一遍基本可以解决 90% 的启动问题。还剩 10% 都集中在爬虫环节比如目标页面结构变化导致选择器失效以及网站反爬导致返回内容为空。这类问题取决于采集时刻的页面结构没有通用解决方案实际处理时就是不断检查 HTML 结构和请求返回状态码逐步缩小问题范围。这里的建议是保留一份清洗后的静态数据文件即使实时爬虫失败分析可视化页面依然可以展示这在答辩演示时是一条十分可靠的后备路径。从那以后我每次拿到这类毕设源码都强制走一遍环境自检流程建独立虚拟环境、锁 Django 版本、确认 MySQL 字符集、先跑后端再开前端、逐个检查静态资源路径。页面空白时先按 F12 看 Network 和 Console 的加载顺序而不是反复刷新页面。这套流程让我在本地配置阶段少花了很多无用功希望帮到你。本文还有配套的精品资源点击获取
返回列表