用Python爬虫+MySQL+pyecharts打造秋招简历数据可视化全流程项目

发布时间:2026/8/31 15:40:04
用Python爬虫+MySQL+pyecharts打造秋招简历数据可视化全流程项目 秋招简历没有拿得出手的项目这次我们来做一条能直接写进简历的完整数据链路用 Python 采集 BOSS 直聘公开职位数据把结构化数据落到 MySQL 数据库再通过 pandas 清洗整理最后用 pyecharts 输出可视化分析图表。这个项目不是单独练一个技能而是把 Python 爬虫、数据库建模、数据清洗、数据可视化四件事串起来面试时可以从数据源讲到报表展示是一个典型的“全流程项目”。项目的核心价值在于三点第一技术栈覆盖面广Python、MySQL、pandas、pyecharts 都是秋招高频考点第二产出物直观职位城市分布、薪资区间、学历要求、经验要求这些图表放到简历附件里一眼就能看懂第三可扩展性强数据量不大时普通笔记本电脑就能跑不需要 GPU也不需要服务器集群。项目配套提供源码、示例数据集和文档其中数据集主要用于保证你刚接触时不用卡在“数据从哪来”这一步可以先把 MySQL 入库和可视化跑通再回头自己增量采集。本文会用适合初学者的方式带你把整个项目跑通先做环境准备再走数据采集模块然后是 MySQL 建库建表、数据清洗、可视化输出最后我会给出简历项目描述模板和面试常见问题。整篇内容按照“能跑通、能验证、能扩展”的思路组织建议先把本文收藏跟着步骤操作一遍再动手改参数。1. 项目核心能力速览能力项说明项目类型数据采集 MySQL 存储 数据可视化分析技术栈Python 3.9、requests、pandas、pymysql、pyecharts数据库MySQL 8.0数据源BOSS 直聘公开职位数据演示环境使用配套示例数据集主要功能职位字段采集、CSV 落盘、MySQL 入库、数据清洗、可视化图表输出交付物采集脚本、建表 SQL、清洗脚本、分析脚本、HTML 图表、项目文档硬件要求普通电脑即可建议 8G 内存以上预留 2G 磁盘空间支持平台Windows / macOS / Linux启动方式命令行执行 Python 脚本是否支持 API支持封装为统计查询 API本文给出 Flask 封装思路是否支持批量任务支持按城市、岗位组合批量采集支持 CSV 批量入库适合人群秋招求职者、数据分析初学者、需要课程设计项目的同学从表格可以看出这个项目最大的优势是门槛低但链路完整。你不需要租服务器在自己的电脑上装好 Python 和 MySQL 就能完成全部操作。批量任务方面虽然示例数据集只有数千条但脚本设计支持多城市、多岗位关键词的组合遍历在合规控制请求频率的前提下可以根据自己的研究需要做增量采集。整个项目运行时的资源占用非常小因为它是 CPU 任务而非模型推理任务。执行数据清洗和可视化时内存占用通常在几百 MB 级别只有在执行全量 CSV 入库和图表渲染的瞬间会有短暂提升。项目运行过程中数据库连接数、Python 进程数和生成的 HTML 文件数量是最需要关注的三个指标。2. 适用场景与使用边界这个项目适合四类人群。第一类是秋招求职者需要一个能体现出“从数据获取到分析展示”完整能力的项目用来应对简历筛选和面试追问。第二类是数据分析方向的初学者已经学过 Python 基础语法和 SQL 基础但不知道这些知识如何组合使用这个项目提供了一个很清晰的应用场景。第三类是计算机类专业做课程设计或毕业设计的同学项目规模适中既不会过于简单也不会超出能力范围。第四类是准备转行数据分析的非科班同学可以用这个项目来补足项目经验面试时多一个可聊的案例。项目能解决的问题也很明确学会用 requests 请求公开网页数据学会把半结构化数据解析成表格学会设计一张合理的职位信息表明确字段类型、索引和字符集学会用 pandas 处理缺失值、去重、薪资区间拆分学会用 pyecharts 输出交互式 HTML 图表。这些技能本身就是数据分析岗位的基础能力要求。但这里必须说清楚边界。这个项目的数据采集部分只适合在合法合规的前提下做小规模学习验证不适合大规模、高频率地采集数据更不应该用来获取用户个人联系方式、薪资明细等敏感信息。运行采集脚本前要确认目标网站的服务条款遵守 robots 协议设置合理请求间隔不对目标站点造成压力。项目配套的示例数据集仅用于教学演示如果要发布分析结论建议基于自己合法获取的数据重新分析避免直接引用示例数据中的结论。此外还要注意BOSS 直聘等招聘平台的页面结构、接口参数、反爬策略都可能调整今天能跑的采集逻辑明天可能因为页面改版而失效。遇到这种情况不要死磕把重点放到“数据入库、清洗、可视化”这条主线上数据缺失时用示例数据集补位把项目流程走通比追求数据量更重要。3. 环境准备与前置条件3.1 安装 Python本项目使用 Python 3.9 及以上版本。如果你是第一次配置 Python 环境建议从官网下载安装包安装时勾选“Add Python to PATH”。安装完成后打开终端验证python --version pip --version如果是绿色版或通过包管理工具安装的 Python请确保python和pip命令能直接在终端中使用。如果系统同时存在 Python 2 和 Python 3可能需要使用python3和pip3命令。3.2 安装 MySQL数据库使用 MySQL 8.0。Windows 环境下使用官方安装包即可macOS 可以通过 Homebrew 安装brew install mysql brew services start mysqlLinux 下使用系统包管理器安装例如 Ubuntusudo apt update sudo apt install mysql-server sudo systemctl start mysql安装完成后建议设置一个单独的测试账号避免长期使用 root 账号连库。这里给出一套参考命令CREATE USER demolocalhost IDENTIFIED BY Demo123456; GRANT ALL PRIVILEGES ON *.* TO demolocalhost; FLUSH PRIVILEGES;3.3 创建虚拟环境并安装依赖建议为项目单独创建虚拟环境避免依赖版本冲突mkdir boss-job-analysis cd boss-job-analysis python -m venv venvWindows 下激活虚拟环境venv\Scripts\activatemacOS / Linux 下激活虚拟环境source venv/bin/activate安装项目依赖pip install requests pandas pymysql pyecharts openpyxl如果你是国内网络环境可以加上清华镜像源加速pip install requests pandas pymysql pyecharts openpyxl -i https://pypi.tuna.tsinghua.edu.cn/simple3.4 项目目录结构参考建议提前把项目目录规划好方便后续管理脚本和数据boss-job-analysis/ ├── src/ # 源码目录 │ ├── fetch_data.py # 数据采集脚本 │ ├── clean_data.py # 数据清洗脚本 │ ├── analyze_data.py # 可视化分析脚本 │ └── config.py # 数据库和公共配置 ├── data/ # 数据目录 │ ├── raw/ # 原始采集数据 │ └── processed/ # 清洗后数据 ├── output/ # 图表输出目录 ├── sql/ │ └── init.sql # 建库建表 SQL ├── docs/ # 项目文档 └── requirements.txt # 依赖清单分目录管理的核心意义是原始数据、中间数据、输出结果互不污染。后续做自动化任务时logs 目录还可以用来存放运行日志。环境准备做完后我们可以进入数据采集模块。4. 数据采集模块设计4.1 采集目标字段做招聘数据分析前首先要明确分析维度。从公开职位信息中可以提取以下核心字段字段含义分析价值job_name职位名称热门岗位榜单、词云company_name公司名称雇主分布salary薪资文本薪资区间分析city城市地域分布experience经验要求招聘门槛分析education学历要求学历结构分析industry行业行业热度对比将上述字段整理成 CSV 文件后后续入库和可视化就有了统一的数据基础。采集脚本只需要输出 CSV 即可不必直接把数据写入数据库这样可以降低耦合度也让每一步都能单独验证。4.2 通用请求模板下面是一段适合教学演示的 requests 请求模板。注意这段代码的目标是把“如何请求页面、如何控制频率、如何解析字段”讲清楚实际项目运行时要根据目标站点的公开页面结构调整 URL 和解析逻辑不要直接照搬import requests import time from bs4 import BeautifulSoup HEADERS { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0 Safari/537.36, Referer: https://www.zhipin.com/ } def fetch_page(url, paramsNone): 请求公开页面返回 HTML 文本。 try: resp requests.get(url, headersHEADERS, paramsparams, timeout10) resp.raise_for_status() # 控制请求间隔这里是关键不要高频请求 time.sleep(3) return resp.text except requests.RequestException as e: print(f请求失败: {e}) return None def parse_job_list(html): 解析职位列表页提取职位名称、公司、薪资、城市、经验、学历等信息。 实际选择器需要根据页面结构调整。 soup BeautifulSoup(html, html.parser) items [] # 此处仅为演示结构具体 class 名称需以实际页面为准 for card in soup.select(.job-card): job_name card.select_one(.job-name).get_text(stripTrue) if card.select_one(.job-name) else company_name card.select_one(.company-name).get_text(stripTrue) if card.select_one(.company-name) else salary card.select_one(.salary).get_text(stripTrue) if card.select_one(.salary) else city card.select_one(.city).get_text(stripTrue) if card.select_one(.city) else experience card.select_one(.experience).get_text(stripTrue) if card.select_one(.experience) else education card.select_one(.education).get_text(stripTrue) if card.select_one(.education) else industry card.select_one(.industry).get_text(stripTrue) if card.select_one(.industry) else items.append({ job_name: job_name, company_name: company_name, salary: salary, city: city, experience: experience, education: education, industry: industry, }) return items写采集脚本时最容易踩的坑有三个请求头缺失导致返回异常页面、请求频率过高触发访问限制、解析选择器写死导致页面改版后失效。建议把请求间隔控制在 3 秒以上并且把解析逻辑单独抽成函数这样页面结构变化时只改一处即可。4.3 数据落盘为 CSV采集到的数据先用 pandas 转成 DataFrame再导出为 CSV 文件import pandas as pd def save_to_csv(items, file_path): df pd.DataFrame(items) df.to_csv(file_path, indexFalse, encodingutf-8-sig) print(f已保存 {len(df)} 条数据到 {file_path})这里使用utf-8-sig编码是为了让生成的 CSV 文件在 Excel 中打开时中文不乱码。如果你使用 pandas 1.3 以上版本CSV 导入导出时建议显式指定encoding参数避免不同操作系统默认编码差异导致乱码。5. MySQL 数据库设计5.1 建库建表 SQL数据库设计是面试时最容易追问的部分。下面这份 SQL 建了一张职位信息表字段类型、字符集、索引都做了基础设计CREATE DATABASE IF NOT EXISTS job_analysis DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; USE job_analysis; CREATE TABLE IF NOT EXISTS job_info ( id INT AUTO_INCREMENT PRIMARY KEY COMMENT 自增主键, job_name VARCHAR(100) COMMENT 职位名称, company_name VARCHAR(100) COMMENT 公司名称, salary_min INT COMMENT 最低月薪(K), salary_max INT COMMENT 最高月薪(K), city VARCHAR(50) COMMENT 工作城市, district VARCHAR(50) COMMENT 城区, experience VARCHAR(50) COMMENT 经验要求, education VARCHAR(50) COMMENT 学历要求, industry VARCHAR(100) COMMENT 公司行业, publish_date DATE COMMENT 发布日期, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 入库时间, KEY idx_city (city), KEY idx_salary_min (salary_min) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENTBOSS直聘职位信息表;这里有几个设计细节值得在面试中主动说出来第一薪资字段不存原始文本而是拆成salary_min和salary_max两个整数列方便做区间统计第二字符集统一使用utf8mb4兼容 emoji 和特殊符号第三对city和salary_min建立普通索引加速后续查询分析第四使用 InnoDB 引擎保证事务支持和并发安全。把 SQL 保存到sql/init.sql文件后在 MySQL 命令行或 Navicat 中执行即可。执行后可以用下面几条 SQL 快速验证表结构SHOW TABLES; DESC job_info; SELECT COUNT(*) FROM job_info;5.2 pandas 批量写入 MySQLMySQL 表建好后就可以用 pymysql 把 CSV 数据批量写入。这里提供一个可运行的写入脚本import pandas as pd from sqlalchemy import create_engine # 注意为了统一字符集建议使用 pymysql 驱动 engine create_engine(mysqlpymysql://demo:Demo123456127.0.0.1:3306/job_analysis?charsetutf8mb4) df pd.read_csv(data/processed/job_clean.csv, encodingutf-8-sig) df.to_sql(job_info, engine, if_existsappend, indexFalse) print(f成功写入 {len(df)} 条数据到 MySQL)如果你不想额外安装 SQLAlchemy也可以直接使用 pymysql 执行批量 INSERT但处理大批量数据时效率较低。to_sql方式速度更快代码更简洁是更推荐的做法。数据写入后要用 SQL 做一次质量检查-- 查看记录总数 SELECT COUNT(*) FROM job_info; -- 查看城市分布 SELECT city, COUNT(*) AS cnt FROM job_info GROUP BY city ORDER BY cnt DESC LIMIT 10; -- 查看空值情况 SELECT COUNT(*) AS missing_cnt FROM job_info WHERE job_name IS NULL OR company_name IS NULL;这三条 SQL 分别验证了数据量、数据分布和数据完整性。只有这三项都通过才能进入下一步可视化分析。6. 数据清洗与薪资解析6.1 缺失值与重复值处理原始采集数据通常存在缺失、重复、格式不统一等质量问题清洗逻辑是 pandas 的强项import pandas as pd df pd.read_csv(data/raw/job_raw.csv, encodingutf-8-sig) print(f原始数据量: {len(df)}) # 1. 删除完全重复记录 df df.drop_duplicates() # 2. 删除关键字段为空的数据 df df.dropna(subset[job_name, company_name, city]) # 3. 其他字段为空时填充默认值 df[experience] df[experience].fillna(经验不限) df[education] df[education].fillna(学历不限) print(f清洗后数据量: {len(df)}) df.to_csv(data/processed/job_clean.csv, indexFalse, encodingutf-8-sig)清洗的取舍需要根据分析目标来定。如果某个字段对你后续的可视化不构成影响删除空值没问题但像“经验”和“学历”这类分析维度直接删除会损失样本量填充默认值更稳妥。6.2 薪资文本拆分为区间原始薪资字段经常是15-25K、20-30K·14薪、面议这类格式。为了做数值分析需要把区间拆成最小值、最大值并统一成月薪单位import re def parse_salary(salary_text): 解析薪资文本返回 (salary_min, salary_max)单位K。 if not isinstance(salary_text, str): return None, None if 面议 in salary_text: return None, None match re.search(r(\d)[Kk]?-(\d)[Kk]?, salary_text) if match: return int(match.group(1)), int(match.group(2)) match re.search(r(\d)[Kk]?, salary_text) if match: salary int(match.group(1)) return salary, salary return None, None df[[salary_min, salary_max]] df[salary].apply( lambda x: pd.Series(parse_salary(x)) ) # 计算平均薪资用于后续分析 df[salary_avg] (df[salary_min] df[salary_max]) / 2这段代码把“面议”薪资设置成缺失值在后续分析中可以根据需要过滤掉。对于只有一个数值的薪资文本例如10K代码会返回相同的最小值和最大值这也是合理的处理方式。6.3 验证清洗结果清洗完成后建议先用describe()和info()做数据质量验证print(df.info()) print(df.describe()) print(df[city].value_counts().head(10)) print(df[[salary_min, salary_max]].head())如果salary_min和salary_max有缺失值说明原始数据中“面议”占比较高后续薪资分析时需要过滤掉这些记录。如果city字段存在“北京·朝阳区”这类复合值还需要继续拆分城市和城区。7. 数据可视化分析7.1 查询数据库数据可视化分析前先从 MySQL 中读取数据。这样你展示给面试官的是一个完整的“数据入库 - 查询分析”闭环import pandas as pd from sqlalchemy import create_engine engine create_engine(mysqlpymysql://demo:Demo123456127.0.0.1:3306/job_analysis?charsetutf8mb4) query SELECT job_name, company_name, salary_min, salary_max, salary_avg, city, experience, education, industry FROM job_info WHERE salary_min IS NOT NULL AND salary_max IS NOT NULL df pd.read_sql(query, engine) print(df.shape)查询条件中过滤掉薪资为空的数据是为了保证可视化图表不会出现大面积空值。你也可以把过滤条件放到数据清洗阶段完成二选一均可重要的是保持整个分析流程的一致性。7.2 城市分布柱状图城市分布是最直观的分析维度。使用 pyecharts 生成交互式柱状图from pyecharts.charts import Bar from pyecharts import options as opts city_counts df[city].value_counts().head(15) bar ( Bar() .add_xaxis(city_counts.index.tolist()) .add_yaxis(职位数量, city_counts.values.tolist()) .set_global_opts( title_optsopts.TitleOpts(titleBOSS直聘职位城市分布 TOP15), xaxis_optsopts.AxisOpts(axislabel_optsopts.LabelOpts(rotate30)), ) ) bar.render(output/city_distribution.html) print(图表已生成: output/city_distribution.html)pyecharts 生成的 HTML 文件可以直接用浏览器打开交互式图表在简历附件和面试现场演示时都比较加分。如果你更习惯静态图片也可以把render改为render_snapshot或使用 matplotlib 生成 PNG。7.3 薪资区间分析薪资分析建议使用箱线图或直方图来展示分布形态。这里给出一个简易的薪资区间分布条形图示例from pyecharts.charts import Bar bins [0, 10, 15, 20, 30, 50, 100] labels [0-10K, 10-15K, 15-20K, 20-30K, 30-50K, 50K以上] df[salary_bin] pd.cut(df[salary_avg], binsbins, labelslabels, rightFalse) salary_dist df[salary_bin].value_counts().sort_index() bar ( Bar() .add_xaxis(salary_dist.index.tolist()) .add_yaxis(职位数量, salary_dist.values.tolist()) .set_global_opts(title_optsopts.TitleOpts(title平均薪资区间分布)) ) bar.render(output/salary_distribution.html)实际分析时还可以增加“城市薪资对比”“岗位类型薪资对比”等维度。把city和salary_avg做分组聚合就能看出不同城市的薪资水平差异这也是面试官比较关注的分析思路。7.4 学历与经验分布学历和经验是招聘门槛的两个核心指标适合用饼图展示占比from pyecharts.charts import Pie edu_counts df[education].value_counts() pie ( Pie() .add(, [list(z) for z in zip(edu_counts.index.tolist(), edu_counts.values.tolist())]) .set_global_opts(title_optsopts.TitleOpts(title学历要求分布)) .set_series_opts(label_optsopts.LabelOpts(formatter{b}: {c} ({d}%))) ) pie.render(output/education_distribution.html)类似的代码可以继续做经验要求分布、热门行业分布、热门职位词云。生成图表时建议统一保存到output目录文件名以分析维度命名方便后续整理成项目报告。7.5 词云与热门职位文本类字段除了条形图还可以做词云。使用wordcloud库可以生成职位名称词云from wordcloud import WordCloud import matplotlib.pyplot as plt text .join(df[job_name].dropna().tolist()) wc WordCloud(font_pathmsyh.ttc, width800, height400, background_colorwhite).generate(text) plt.figure(figsize(10, 5)) plt.imshow(wc, interpolationbilinear) plt.axis(off) plt.savefig(output/job_wordcloud.png, dpi150)需要注意font_path要指向系统中文字体文件。Windows 下通常是msyh.ttcmacOS 下是/System/Library/Fonts/PingFang.ttc。如果不指定中文字体词云中的中文会显示为方框。8. 项目结果与简历写法8.1 项目能证明哪些技能一个完整的 Python MySQL 数据分析项目在简历上可以直接体现以下能力Python 基础requests 请求、BeautifulSoup 解析、pandas 数据处理。MySQL建库建表、索引设计、数据导入、SQL 查询验证。数据分析数据清洗、缺失值处理、薪资字段拆分、多维度聚合。可视化pyecharts / matplotlib 输出交互式图表形成分析结论。工程能力项目目录分层、配置管理、批量任务设计、异常处理。8.2 简历项目描述模板这里给出一段可以直接修改使用的项目描述模板BOSS直聘职位数据可视化分析Python MySQL 技术栈Python、requests、pandas、MySQL、pyecharts 项目描述 1. 通过 requests 采集 BOSS 直聘公开职位信息解析职位名称、公司、薪资、城市、经验、学历、行业等核心字段并落盘为 CSV。 2. 设计 MySQL 职位信息表完成建库建表、索引优化使用 pandas 批量写入数据支持多城市多岗位批量采集任务。 3. 使用 pandas 完成数据清洗标注、薪资区间拆分、缺失值处理输出规范化分析数据集。 4. 使用 pyecharts 生成城市分布、薪资区间、学历要求、经验要求、热门行业等交互式图表。 5. 结合图表输出分析结论形成数据报告支撑求职者职位选择与薪资预期判断。写简历时有几个建议项目名称不要只写“爬虫项目”要写成“数据可视化分析项目”技术栈尽量写全但不要夸大描述要突出“你做了什么”而不是“你知道了什么”如果生成过报告或图表附件可以在简历末尾附上 GitHub 链接或在线预览地址。8.3 面试常见问题这个项目在面试中容易被追问的点包括采集到的数据是如何清洗的缺失值和重复值怎么处理薪资字段为什么拆成最小值、最大值还有其他处理方式吗建表时为什么选择 InnoDB索引为什么建在 city 和 salary_min 上如果数据量从几千条变成几百万条你的方案瓶颈在哪里如何控制采集频率如果遇到反爬你会怎么调整策略回答这些问题时重点是展示你的思考过程而不是背答案。比如“如果数据量变到几百万条我会考虑分表分区、增加缓存、优化索引、使用分布式采集”这类回答比单纯背概念更有说服力。9. 常见问题与排查方法问题现象可能原因排查方式解决方案MySQL 连接失败服务未启动或账号密码错误检查 MySQL 服务状态用命令行测试连接启动服务确认账号权限数据写入 MySQL 后中文乱码字符集不一致检查建库字符集和连接字符集统一使用 utf8mb4连接串加 charsetutf8mb4pandas 读取 CSV 中文乱码编码不匹配用文本编辑器打开原始 CSV统一使用 utf-8-sig 编码依赖安装失败网络问题或版本冲突查看 pip 报错信息使用国内镜像源或指定版本重装HTML 图表打不开文件路径错误或未生成成功查看 output 目录文件确认脚本运行成功用浏览器直接打开采集请求返回异常页面请求头缺失或请求过于频繁打印响应状态和内容片段补全请求头增大请求间隔薪资解析结果大量为 None正则不匹配“面议”或格式异常打印原始薪资文本样本增加正则分支补充薪资格式规则批量任务中途卡住网络超时或数据库连接断开查看日志输出增加超时重试机制自动重连数据库这里说一个最容易被忽略的问题MySQL 的max_allowed_packet默认值在批量写入大数据量 DataFrame 时可能不够导致to_sql报错。如果遇到这种状况可以通过 SQL 调整SET GLOBAL max_allowed_packet 64 * 1024 * 1024;同时检查本地端口 3306 是否被占用尤其是安装过 Docker 或多个数据库实例的电脑容易因为端口冲突导致客户端连接失败。如果端口冲突可以修改 MySQL 配置文件中的port参数。10. 最佳实践与扩展方向10.1 工程化建议第一次跑通时先只用示例数据集做分析不要一上来就写采集脚本把 MySQL 建库和可视化流程跑通后再增加采集模块。所有脚本都增加日志输出至少打印当前执行阶段和数据量方便定位问题。采集脚本必须设置请求间隔和失败重试机制合理范围内的间隔可以显著降低被封风险。原始数据、清洗后数据、输出图表分目录保存避免中间文件覆盖。MySQL 连接配置单独放在config.py中不要硬编码在脚本里。涉及密码的文件在提交到 Git 前最好用环境变量占位。定期备份数据库。数据量不大时直接使用mysqldump即可。mysqldump -u demo -p job_analysis backup.sql10.2 扩展方向这个项目可以继续扩展成更大规模的数据分析系统用 Flask 或 FastAPI 封装统计接口查询某城市的平均薪资、岗位数量、学历占比等。使用 Streamlit 把可视化图表做成在线看板。增加时间维度按周、按月分析职位发布量趋势。增加职位描述文本挖掘提取技能关键词分析岗位技能要求。引入 Airflow 或 Cron 定时任务实现周期性增量采集与分析。以 Flask 接口封装为例下面是一个通用统计接口框架from flask import Flask, jsonify import pandas as pd from sqlalchemy import create_engine app Flask(__name__) engine create_engine(mysqlpymysql://demo:Demo123456127.0.0.1:3306/job_analysis?charsetutf8mb4) app.route(/api/stat/city/city) def stat_city(city): query f SELECT COUNT(*) AS cnt, AVG(salary_min) AS avg_salary_min, AVG(salary_max) AS avg_salary_max FROM job_info WHERE city {city} df pd.read_sql(query, engine) return jsonify(df.to_dict(orientrecords)[0]) if __name__ __main__: app.run(host127.0.0.1, port8000)接口封装好后前端页面、数据分析脚本、外部系统都能通过 HTTP 请求获取统计数据项目的应用价值也更完整。11. 总结这个项目最值得尝试的点是它把 Python、MySQL、pandas、pyecharts 四块秋招高频技能串成了一条完整链路。你不需要在高配置服务器上运行普通笔记本电脑就能跑通全部流程。第一优先级要验证的功能是 MySQL 建库和 pandas 写入因为只要数据能正常入库后面的清洗和可视化基本不会出大问题。最容易踩的坑集中在三处MySQL 连接配置、中文字符集、采集请求频率控制这三项提前做好规划项目进度会顺畅很多。后续如果你要做增量采集可以先从小批量、低频率开始逐步扩大范围。再把分析结果封装成 API 或在线看板这个项目就能从“课程设计”升级为“数据分析小系统”。建议把源码、数据集、文档和输出图表都整理好简历附件里放一张可视化截图面试时直接带着项目经验去聊比单纯罗列技能更有说服力。收藏起来按本文的步骤跑一遍你的简历上又多了一个能写进“项目经验”的完整案例。