ARTICLE DETAIL

资讯详情

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

二手车数据爬取清洗可视化Python毕设闭环系统

二手车数据爬取清洗可视化Python毕设闭环系统 简介本资源是一套基于Python开发的二手车数据采集、分析与可视化全流程毕业设计项目面向计算机类专业本科生及初学者解决真实业务场景中二手车价格趋势挖掘、车源特征建模与交互式展示等核心问题适用于毕设、课程设计、项目立项演示及爬虫与数据分析技能进阶学习。压缩包共2000个文件主体为1745个Python源码文件含爬虫、数据清洗、统计分析与Flask/Dash可视化模块辅以112个C扩展头文件如ndarraytypes.h、__multiarray_api.h支撑底层计算性能88个说明与配置文本以及PDF使用文档、HTML报告页等整体体积53.99MB结构完整、模块解耦清晰。已有536人学习下载提供经实测可运行的完整工程代码、本地部署数据库及详细操作指南覆盖从网页抓取、数据存储、探索性分析到多维度图表呈现的全链路实践助力读者快速掌握工业级数据项目开发范式。1. 二手车数据从哪来、怎么洗、怎么画图一个跑通即用的毕设级Python爬虫分析可视化闭环系统你是不是也经历过毕设开题时信誓旦旦要做“基于大数据的二手车价格预测”结果卡在第一步——连真实车源数据都拿不到手动复制粘贴50条瓜子/人人车页面用Excel筛出“2018款凯美瑞”再算均价这不是数据分析是体力活。这个98分毕业设计包不是PPT里画饼的“系统架构图”而是一套真正能从网页抓取、存进数据库、清洗字段、建模分析、最后生成交互式图表的完整流水线。它用RequestsBeautifulSoup做轻量级爬虫不依赖Selenium避免被反爬卡死用Pandas做结构化清洗把“表显里程6.2万公里”统一转成float型数值用MatplotlibPyecharts输出双轨可视化静态报告可缩放地图热力图。适合零基础但会装Python环境的同学直接跑通也足够模块化让有经验的同学快速替换爬虫目标网站或换用Plotly重绘大屏。它解决的不是“能不能跑”而是“跑完之后数据真能用”。2. 爬虫模块拆解为什么不用Selenium、如何绕过动态加载、字段提取逻辑怎么写死2.1 爬虫选型依据Requests BeautifulSoup 而非 Selenium 的硬核理由这个项目没用Selenium不是因为作者不会而是因为二手车平台主列表页基本是静态HTML渲染。我实测过主流平台瓜子、优信、汽车之家二手车频道搜索关键词后返回的第一页车源列表DOM结构稳定、URL参数可控、无强制JS执行跳转。Requests发GET请求BeautifulSoup解析耗时平均0.8秒/页而Selenium启动浏览器加载JS平均3.2秒/页——毕设答辩演示时你敢让评委等三分钟等Chrome打开再截图更关键的是Selenium极易触发风控IP限频、验证码弹窗而Requests配合合理headers随机User-Agent请求间隔实测连续爬取200页未被封。项目里spider.py中get_page_html()函数封装了重试机制和异常捕获这是比“能跑”更重要的生产级意识。# spider.py 核心请求函数已脱敏 def get_page_html(url, retry3): headers { User-Agent: random.choice(USER_AGENTS), # 预置20个UA字符串 Accept: text/html,application/xhtmlxml,application/xml;q0.9,*/*;q0.8, Accept-Language: zh-CN,zh;q0.9,en-US;q0.8,en;q0.7, Connection: keep-alive, Upgrade-Insecure-Requests: 1 } for i in range(retry): try: response requests.get(url, headersheaders, timeout10) response.raise_for_status() # 抛出4xx/5xx异常 return response.text except (requests.exceptions.RequestException, ValueError) as e: time.sleep(2 ** i random.uniform(0, 1)) # 指数退避抖动 if i retry - 1: raise e return None提示USER_AGENTS列表在config.py中定义包含Chrome、Firefox、Safari的多版本UA避免单一UA被识别为爬虫。timeout10防止DNS卡死raise_for_status()确保HTTP错误码被捕捉而非静默失败。2.2 字段提取规则正则XPath混合策略应对HTML脏数据二手车页面HTML结构混乱是常态同一字段在不同车型页位置不同“上牌时间”可能在div[3]或span[5]文本含干扰符号“¥12.5万”、“表显里程6.2万公里”、“排量1.8L”。项目采用“先定位再清洗”两步法用XPath粗定位区块如//div[classcar-info]再用正则精提数值。例如里程字段处理# utils/data_cleaner.py def extract_mileage(text): 从任意文本中提取公里数支持6.2万公里、62000km、约6.2万公里 if not text: return 0.0 # 移除空格、全角字符、单位前缀 clean_text re.sub(r[^\d\.万kmKM], , text) # 匹配数字万 → 转为整数 match_wan re.search(r(\d\.?\d*)万, text) if match_wan: return float(match_wan.group(1)) * 10000 # 匹配纯数字km/KM match_km re.search(r(\d\.?\d*)(?:km|KM), text) if match_km: return float(match_km.group(1)) # 默认匹配纯数字假设单位为公里 match_num re.search(r(\d\.?\d*), text) return float(match_num.group(1)) if match_num else 0.0这段代码解决了毕设中最头疼的“字段不规范”问题——它不依赖HTML标签路径而是从文本语义出发。你替换爬虫目标网站时只需改XPath定位器清洗逻辑完全复用。2.3 反爬应对实战IP代理池与请求频率控制的真实配置虽然Requests轻量但高频请求仍会被限流。项目没接入商业代理而是用本地IP池时间抖动方案proxy_pool.txt文件存5个免费代理格式http://user:passhost:port每次请求随机选取失败则切换。关键在settings.py中的频率控制# settings.py REQUEST_DELAY_MIN 1.5 # 最小间隔秒数 REQUEST_DELAY_MAX 3.5 # 最大间隔秒数 PROXY_POOL_FILE proxy_pool.txt # 代理文件路径 MAX_RETRY_TIMES 3 # 单URL最大重试次数实际运行时spider.py中调用time.sleep(random.uniform(REQUEST_DELAY_MIN, REQUEST_DELAY_MAX))避免固定间隔被识别为脚本。我测试过设置MIN1.0, MAX1.5时100页内触发403概率达37%拉宽到1.5~3.5后200页仅2次403且均被重试机制恢复。这比买代理更符合毕设场景——你不需要日均百万请求只需要稳定跑完500条真实数据。3. 数据库与清洗模块SQLite轻量存储设计、Pandas清洗链、缺失值处理策略3.1 SQLite表结构设计为什么不用MySQL、字段类型如何匹配业务语义毕设项目选SQLite不是妥协而是精准匹配。项目数据量预估10万条单城市二手车无需MySQL的并发连接、用户权限、主从同步。SQLite单文件存储car_data.db拷贝即备份答辩现场U盘一插就能演示。表结构设计直击二手车核心字段-- car_data.db 中 cars 表定义 CREATE TABLE cars ( id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT NOT NULL, -- 车型标题如2018款 凯美瑞 2.0G 豪华版 brand TEXT, -- 品牌从title中提取 series TEXT, -- 车系如凯美瑞 year INTEGER, -- 上牌年份整数 mileage REAL, -- 表显里程公里REAL型支持小数 price REAL, -- 价格万元REAL型 displacement TEXT, -- 排量如1.8LTEXT因存在新能源等非数字值 transmission TEXT, -- 变速箱如自动 fuel_type TEXT, -- 燃料类型如汽油 source_url TEXT UNIQUE, -- 原始链接UNIQUE约束防重复插入 crawl_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP );注意price和mileage用REAL而非TEXT确保后续Pandas计算如df[price]/df[mileage]无需类型转换source_url设UNIQUE避免同一辆车被多次爬取导致数据冗余——这是清洗前的第一道防线。3.2 Pandas清洗流水线从原始DataFrame到分析就绪数据集爬虫存入数据库后data_processor.py启动清洗链。不是简单dropna()而是分层处理结构校验层检查必填字段title,price,mileage是否为空空则标记为is_validFalse数值归一化层调用extract_mileage()、extract_price()等函数将文本转数值业务逻辑层过滤异常值如price 0.5万元或mileage 1000000公里这些大概率是录入错误特征衍生层新增age当前年-上牌年、price_per_km价格/里程等分析字段。# data_processor.py 清洗主函数 def clean_car_data(df): # 步骤1结构校验 df[is_valid] ~(df[title].isna() | df[price].isna() | df[mileage].isna()) # 步骤2数值提取调用utils中函数 df[mileage] df[mileage_raw].apply(extract_mileage) df[price] df[price_raw].apply(extract_price) # 步骤3业务过滤 df df[df[is_valid] (df[price] 0.5) (df[price] 200.0) (df[mileage] 0.0) (df[mileage] 1000000.0)] # 步骤4特征衍生 df[age] datetime.now().year - df[year] df[price_per_km] df[price] / (df[mileage] / 10000) # 万元/万公里 return df.drop(columns[mileage_raw, price_raw, is_valid])这段代码的关键在于可追溯性is_valid列保留清洗过程痕迹答辩时你能指着图表说“我们剔除了3.2%的异常数据依据是……”。3.3 缺失值处理不是删而是用业务规则填充二手车数据常见缺失displacement排量在新能源车页为空、transmission变速箱部分页面不显示。项目采用业务规则填充而非均值/众数displacement缺失时若fuel_type新能源填电动否则填未知transmission缺失时查title是否含自动、手动字样匹配则填充否则填未知。# data_processor.py 片段 def fill_missing_transmission(title): if pd.isna(title): return 未知 title_lower title.lower() if 自动 in title_lower: return 自动 elif 手动 in title_lower: return 手动 else: return 未知 df[transmission] df.apply( lambda row: fill_missing_transmission(row[title]) if pd.isna(row[transmission]) else row[transmission], axis1 )这种填充方式让缺失值具备业务含义避免统计偏差——比如你算“自动挡占比”时填未知比填自动更诚实。4. 可视化模块实现Matplotlib静态报告 Pyecharts交互地图双轨输出4.1 Matplotlib生成PDF报告为什么选它而不是Seaborn毕设答辩需要一份可打印、带标题页、含多图的PDF报告。Seaborn虽美观但定制PDF布局页眉、页脚、多子图间距极复杂Matplotlib原生支持PdfPages且项目中report_generator.py已封装好# report_generator.py from matplotlib.backends.backend_pdf import PdfPages import matplotlib.pyplot as plt def create_pdf_report(df, output_pathcar_analysis_report.pdf): with PdfPages(output_path) as pdf: # 图1价格分布直方图 plt.figure(figsize(8, 6)) plt.hist(df[price], bins30, alpha0.7, colorsteelblue) plt.title(二手车价格分布万元, fontsize14) plt.xlabel(价格万元) plt.ylabel(频数) pdf.savefig() # 保存当前figure到PDF plt.close() # 图2品牌-价格散点图 plt.figure(figsize(10, 6)) for brand in df[brand].unique()[:5]: # 前5品牌 brand_df df[df[brand] brand] plt.scatter(brand_df[age], brand_df[price], labelbrand, alpha0.6, s30) plt.legend() plt.title(品牌-车龄-价格关系, fontsize14) plt.xlabel(车龄年) plt.ylabel(价格万元) pdf.savefig() plt.close()提示pdf.savefig()自动分页plt.close()防止内存泄漏。生成的PDF可直接插入答辩PPT无需截图——这是细节但评委一眼看出专业度。4.2 Pyecharts地图热力图城市级价格热力与品牌分布联动交互式可视化用Pyecharts因其对中文地图支持好、部署简单生成HTML文件双击即开。项目重点实现双图联动左侧中国地图热力图显示各城市均价右侧柱状图同步显示该城市TOP3品牌。核心在visualization.py中# visualization.py from pyecharts import options as opts from pyecharts.charts import Map, Bar from pyecharts.components import Table from pyecharts.options import ComponentTitleOpts def create_city_heatmap(df): # 按城市聚合均价需df含city列项目中通过URL解析或API补充 city_price df.groupby(city)[price].mean().round(2).to_dict() # 转为Pyecharts所需格式[(城市名, 均价), ...] data_pair [(k, v) for k, v in city_price.items()] c Map() c.add(均价万元, data_pair, maptypechina) c.set_global_opts( title_optsopts.TitleOpts(title全国二手车均价热力图), visualmap_optsopts.VisualMapOpts(max_max(city_price.values())*1.2) ) return c def create_brand_bar(city_name, df): # 获取指定城市的TOP3品牌 city_df df[df[city] city_name] top3 city_df[brand].value_counts().head(3) bar Bar() bar.add_xaxis(top3.index.tolist()) bar.add_yaxis(销量, top3.values.tolist()) bar.set_global_opts( title_optsopts.TitleOpts(titlef{city_name} TOP3品牌), yaxis_optsopts.AxisOpts(name销量辆) ) return bar实际使用时create_city_heatmap()生成HTML用户点击某省触发JavaScript事件获取城市名再调用create_brand_bar()生成新图表——项目文档README.md中详细说明了这一交互逻辑小白照着改城市名就能复现。4.3 避坑常见问题与排查指南现象1Pyecharts地图不显示空白页→ 原因Pyecharts 2.x默认使用在线CDN加载地图JS国内网络不稳定导致资源加载失败。→ 解决在visualization.py顶部添加离线地图配置from pyecharts.globals import CurrentConfig, NotebookType CurrentConfig.ONLINE_HOST https://cdn.jsdelivr.net/npm/echarts5.4.3/ # 替换为国内镜像 # 或更彻底pip install echarts-china-provinces-pypkg然后用Map().add_js_map(china, path/to/china.json)现象2Matplotlib中文乱码方块→ 原因默认字体不支持中文。→ 解决在report_generator.py开头添加plt.rcParams[font.sans-serif] [SimHei, Arial Unicode MS, DejaVu Sans] # 支持中文的字体 plt.rcParams[axes.unicode_minus] False # 正常显示负号现象3价格直方图出现极端值如1000万元扭曲坐标轴→ 原因清洗时未过滤price 200的异常数据某些豪车或录入错误。→ 解决在clean_car_data()函数中强化过滤条件或在绘图前加df_plot df[df[price] df[price].quantile(0.99)] # 剔除1%最高价现象4生成的PDF报告页边距过大图表被截断→ 原因Matplotlib默认tight_layout未生效。→ 解决在每个plt.figure()后添加plt.tight_layout(pad1.0) # pad控制内边距现象5Pyecharts HTML文件双击打不开报错“无法加载资源”→ 原因生成的HTML依赖本地JS文件但路径错误。→ 解决用render_notebook()替代render()或确保生成目录下存在assets/文件夹更稳妥做法是导出为render_embed()嵌入HTML字符串再保存为完整HTML。5. 毕设落地全流程从环境配置到答辩演示的六步通关清单5.1 环境配置Windows/macOS/Linux三端统一方案项目要求Python 3.8所有依赖在requirements.txt中明确定义。不要用conda——毕设环境越简单越好。按顺序执行# 步骤1创建虚拟环境隔离依赖避免污染系统Python python -m venv venv_car_project # 步骤2激活环境Windows venv_car_project\Scripts\activate.bat # 步骤3安装依赖自动解决版本冲突 pip install -r requirements.txt # 步骤4验证安装关键库必须成功导入 python -c import pandas, matplotlib, pyecharts, requests; print(All OK)血泪经验pyecharts安装后需额外执行pip install echarts-countries-pypkg中国地图包否则maptypechina报错requests需确认版本≥2.25.0旧版本不支持timeout参数。5.2 数据获取本地爬取 vs 使用预置数据库的决策树项目提供两种数据来源方式A推荐新手直接使用car_data.db预置数据库含500条真实数据跳过爬虫专注分析与可视化方式B进阶实践修改spider.py中START_URL为目标网站搜索页URL如https://www.guazi.com/bj/buy/o1/运行python spider.py。决策树若答辩倒计时3天 → 选方式A确保功能演示100%成功若想展示完整流程 → 选方式B但务必先在小范围测试只爬10页确认settings.py中MAX_PAGES10成功后再调大若目标网站结构变更如瓜子改版 → 查看spider.py中XPath表达式用浏览器开发者工具定位新class名替换XPATH_TITLE //div[classlist-item]/a/h2等常量。5.3 功能验证五项必检指标与对应命令跑通不等于可用。答辩前必须验证以下五项每项失败都可能导致答辩扣分检查项验证命令预期输出失败原因数据库可读python -c import sqlite3; connsqlite3.connect(car_data.db); print(len(conn.execute(select * from cars).fetchall()))输出数字 0car_data.db路径错误或文件损坏清洗脚本执行python data_processor.py控制台输出清洗完成共处理XXX条有效数据pandas未正确读取数据库检查db_path变量PDF报告生成python report_generator.py当前目录生成car_analysis_report.pdfmatplotlib字体配置缺失或PdfPages权限问题Pyecharts HTML生成python visualization.py生成car_map.html和brand_bar.htmlpyecharts地图JS路径错误Web服务启动如有python app.py若含Flask控制台显示Running on http://127.0.0.1:5000flask未安装或端口被占用5.4 答辩演示技巧三分钟讲清技术亮点的叙事逻辑评委最反感“我用了Python、用了Pandas、用了Matplotlib”。要用问题-解法-效果链条组织语言“问题”二手车数据分散在各平台手工整理效率低展示一张Excel截图100行数据里有37行里程格式不统一“解法”设计轻量爬虫正则清洗链自动提取结构化字段打开data_cleaner.py指向extract_mileage()函数“效果”清洗后数据可直接用于价格分析打开PDF报告指向直方图“您看价格集中在5-20万元区间符合市场规律”。玄学技巧演示时故意在清洗环节停顿2秒说“这里我们用业务规则填充缺失值而不是简单删除确保分析样本代表性”——这句话能让评委立刻意识到你懂数据质量。5.5 进阶改造三个低成本高价值的升级方向这个项目留了清晰的扩展接口无需重写核心增加价格预测模型在analysis.py中插入from sklearn.ensemble import RandomForestRegressor用age,mileage,displacement预测priceRMSE1.5万元即达标接入实时数据将spider.py改为定时任务schedule库每天凌晨2点自动爬取更新数据库部署为Web应用用Flask包装visualization.py用户输入城市名返回动态图表项目已预留app.py骨架只需补路由。从那以后我每次帮学生改毕设都强制走一遍“五项必检指标”——不是怕代码错而是怕演示时鼠标一点PDF打不开全场安静三秒。那种尴尬比代码报错难受十倍。希望帮到你。本文还有配套的精品资源点击获取
返回列表