Python + MySQL 招聘数据分析可视化项目全流程实战

Python + MySQL 招聘数据分析可视化项目全流程实战 毕业设计准备做就业数据分析简历里想放一个可视化项目很多同学都会想到用 Python 配合 MySQL。这类项目最适合的落地方式不是只在 Jupyter Notebook 里跑一段代码而是把数据集、数据库、分析脚本、图表输出整理成一条完整链路先用 Python 清洗数据再把干净数据导入 MySQL接着用 SQL 和 pandas 做统计最后用 pyecharts 生成可视化页面。下面按这个顺序把项目拆开讲每一步都会解释为什么这样做也会把常见报错和排查方式放在一起。这个项目对秋招简历和课设答辩最大的价值在于它覆盖了数据分析方向最常见的工程动作数据格式处理、数据库表设计、SQL 聚合统计、Python 分析调用、图表结果导出。你不需要追求平台前端那种华丽大屏先把“数据清洗到入库、入库到出图”这条闭环跑通比堆砌图表更重要。1. 先理解这个项目到底在分析什么1.1 项目链路从原始数据到可视化页面招聘数据分析可视化拆开看只有三个环节数据存哪里、数据怎么算、结果怎么展示。数据存哪里使用 MySQL。招聘岗位数据是结构化数据适合用关系型数据库存储。数据怎么算使用 SQL 做分组统计再用 pandas 做结果加工。SQL 负责聚合Python 负责补足复杂逻辑和绘图前的数据准备。结果怎么展示使用 pyecharts 生成 HTML 图表页面。图表文件可以直接在浏览器打开也可以放进课设报告或者后续用 Web 框架包装成部署页面。常见完整目录结构是这样recruit_analysis/ ├── data/ │ ├── raw_recruit.csv │ └── clean_recruit.csv ├── sql/ │ ├── create_table.sql │ └── analysis_queries.sql ├── scripts/ │ ├── clean_data.py │ ├── load_to_mysql.py │ ├── analysis.py │ └── charts.py ├── output/ │ ├── city_top10.html │ └── edu_pie.html ├── README.md └── requirements.txt这样组织的好处是输入数据、建表逻辑、运行脚本、结果输出互不混在一起。后续排错时只要确认问题发生在哪一层就能缩小检查范围。1.2 为什么选 Python MySQL而不是只靠 ExcelExcel 确实可以完成筛选、透视表、简单图表但它很难形成可复现的工程化流程。真实招聘数据可能不断追加新字段Excel 手工操作容易出错也无法方便地应对上千上万行数据。Python MySQL 的典型收益如下表。对比项Excel 手工操作Python MySQL清洗过程操作步骤依赖人工记忆清洗逻辑写成脚本可重复运行数据规模几万行会比较吃力可以扩展到百万行级项目聚合分析透视表直观但难以批量执行SQL 分组统计稳定可控图表展示依赖 Excel 环境pyecharts 输出 HTML可分享可嵌入简历表达展示价值有限能体现工程链路适合面试讲解不是说 Excel 不能分析而是写项目时需要更完整的技术链路方便你讲清楚“数据从哪来、如何存储、如何计算、如何展示”。1.3 数据集字段与合规边界很多同学第一反应是“能不能直接写爬虫抓招聘平台数据”。这里建议明确项目边界招聘数据分析项目的重点是分析与可视化不是采集。网站用户协议、访问频率、登录限制、反爬机制都可能让爬虫方案不符合合规要求。更稳妥的做法是使用课程自带样例数据集、公开竞赛数据或者自己根据公开职位信息整理模拟数据。整理后的 CSV 结构可以参考如下字段字段名含义分析用途示例值job_name岗位名称筛选目标岗位、统计岗位类型数据分析师company_name公司名称公司主体标识示例科技有限公司city工作城市地域需求分析上海salary_min月薪下限单位 K薪资区间分析15salary_max月薪上限单位 K薪资区间分析25exp_req经验要求经验门槛分布3-5年edu_req学历要求学历门槛分布本科company_type公司类型公司行业属性互联网company_size公司规模公司规模分布100-499人skill_tags技能标签技能关键词统计SQL,Pythonpublish_date发布日期岗位发布时间趋势2025-01-15如果你手上的原始数据字段不同先不要急着建表而是写一个字段映射脚本做统一避免后面查询时到处是别名混乱。2. 环境准备Python 与 MySQL 的最小可运行状态2.1 版本组合和依赖安装这个项目对版本要求并不苛刻。推荐使用 Python 3.9 及以上版本MySQL 使用 8.0 或 5.7 都可以。下方是建议环境。环境版本建议说明Python3.9 及以上兼容 pandas、pyecharts 新版本MySQL8.0 / 5.7课程和毕设项目都能满足pandas最新稳定版数据清洗和分析SQLAlchemy2.x统一连接 MySQL支持 read_sql、to_sqlPyMySQL1.0 及以上Python 连接 MySQL 的驱动pyecharts2.x生成 HTML 图表环境安装后先执行基础检查python --version pip --version mysql --version如果 MySQL 还没有安装可以按操作系统选择安装方式。Ubuntu/Debian 环境通常使用 apt 安装CentOS/RHEL 环境使用 yumWindows 和 macOS 可以下载安装包。无论哪种方式安装后都需要确认 MySQL 服务处于启动状态。项目依赖可以用一条命令安装pip install pandas pymysql sqlalchemy pyecharts这里不推荐把 matplotlib 当作主力虽然它可以画静态折线图和柱状图但招聘数据分析项目如果要输出给课设答辩或放进简历展示pyecharts 生成的交互式 HTML 更直观也更贴近“可视化”这个关键词。2.2 使用 SQLAlchemy 连接本地 MySQL许多教程会直接使用 PyMySQL 的connect()方法但后续调用 pandas 的read_sql和to_sql时更稳定的方式是使用 SQLAlchemy 连接引擎。下面是一个连接本地数据库的最小示例from sqlalchemy import create_engine # 把 your_password 换成你的 MySQL root 密码 engine create_engine( mysqlpymysql://root:your_passwordlocalhost:3306/recruit?charsetutf8mb4 ) with engine.connect() as conn: print(连接成功)这段代码里的数据库名是recruit。如果还没有创建这个库连接会报Unknown database所以可以先到 MySQL 命令行创建CREATE DATABASE IF NOT EXISTS recruit DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;使用utf8mb4而不是utf8是为了避免中文和部分特殊字符存储时报错或乱码。2.3 环境检查清单每次环境搭建完成后建议按下面的顺序检查一遍。检查项检查命令通过标志Python 版本python --version显示 3.xpip 版本pip --version正常输出版本号MySQL 服务mysqladmin -u root -p status输入密码后显示服务器运行中数据库连接mysql -u root -p进入 MySQL 命令行Python 依赖python -c import pandas,pymysql,sqlalchemy;print(OK)输出 OK如果你在本机运行优先用 root 账号跑通项目。如果连到远程 MySQL需要确认服务器允许远程连接并且端口 3306 可以被访问。学习环境最稳妥的顺序是先本地跑通再考虑远程联调。3. 数据结构与导入从 CSV 到 MySQL 的核心步骤3.1 理解原始字段薪资不要只存一个字符串招聘数据中最容易出错的是薪资字段。很多原始 CSV 会把薪资写成“15-25K”这样的字符串如果直接入库后续想做排序、均值、区间比较都非常麻烦。正确做法是在清洗阶段拆分字段salary_min存 15salary_max存 25。单位统一为 K。这样数据库里可以用数值计算也能画“薪资中位数”之类的图表。保存方式查询示例问题字符串“15-25K”无法用 AVG 计算平均薪资字符串排序会得到错误结果salary_min15salary_max25AVG((salary_minsalary_max)/2.0)数值计算稳定这也解释了为什么原始数据准备好后不要直接复制到 Excel 做人工处理而是要写 Python 清洗脚本。脚本可以反复运行后续拿到增量数据也能复用同样的规则。3.2 数据清洗编码、空值、类型转换先用 pandas 读入 CSV并统一列名import pandas as pd df pd.read_csv(data/raw_recruit.csv, encodingutf-8-sig) print(df.shape) print(df.head())encodingutf-8-sig是处理中文 CSV 的常用写法。Windows 下用 Excel 导出的文件可能带有 BOM不指定utf-8-sig会让第一列列名出现\ufeff前缀。假设原始文件列名是中文先做字段映射df df.rename(columns{ 岗位名称: job_name, 公司名称: company_name, 城市: city, 最低薪资: salary_min, 最高薪资: salary_max, 经验要求: exp_req, 学历要求: edu_req, 公司类型: company_type, 公司规模: company_size, 技能标签: skill_tags, 发布时间: publish_date, })再做类型转换和缺失值处理df[salary_min] df[salary_min].astype(int) df[salary_max] df[salary_max].astype(int) df[publish_date] pd.to_datetime(df[publish_date], errorscoerce).dt.date df df.dropna(subset[job_name, city, salary_min, salary_max]) df[job_name] df[job_name].str.strip() df[city] df[city].str.strip() df.to_csv(data/clean_recruit.csv, indexFalse, encodingutf-8-sig)这里有一个需要特别注意的坑不要对所有数据源套用同一套清洗代码。例如原始字段若是“15K-25K·14薪”简单astype(int)就会报错。碰到这种情况要先写一个解析函数剥掉非数字部分或者回到数据导出源头统一格式。正规项目流程里清洗规则应当记录在 READ