尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

Python二手房爬虫与房价预测全流程源码解析:从数据抓取到机器学习建模

发布时间:2026/9/28 1:39:18

资讯中心
01
ARTICLE

Python二手房爬虫与房价预测全流程源码解析:从数据抓取到机器学习建模

Python二手房爬虫与房价预测全流程源码解析:从数据抓取到机器学习建模
简介这份源码资源面向具备Python基础、希望入门数据采集与机器学习实战的学生和开发者围绕房天下二手房场景完整呈现从爬虫抓取、数据清洗理解到可视化分析与房价预测建模的全流程。资源包共93个文件、约13.71MB以42个Python脚本为核心覆盖随机请求头爬虫、数据清洗、数据理解、可视化及模型预测等模块另含31张PNG分析图表、6个CSV数据文件、5个XML配置及Markdown文档、xlsx表格等便于对照代码与结果复现实验。目前已有175人学习下载。读者可借此掌握反爬请求头模拟、探索性数据分析、箱线图与年份总价关系等可视化方法并基于历史房价数据训练预测模型理解特征与总价之间的关联为课程实训、毕业设计或房地产数据分析项目提供可直接参考的完整实现与排错思路。1. 从一份 92 文件的实训包说起这套房天下二手房爬虫与房价预测源码能跑出什么如果你正在找一套能直接跑通的「爬虫 数据分析 房价预测」完整链路源码这套 2024 年夏季小学期实训项目值得拆一拆。它用 Python 把房天下二手房数据从抓取、清洗、可视化一路做到机器学习建模源码包共 92 个文件其中 41 个 Python 脚本、31 张 PNG 图表、5 个 CSV 数据文件外加配置、文档和一份 xlsx。和网上那种只丢一个spider.py的碎片代码不同它把「爬虫-随机请求头.py」「数据清洗.py」「数据理解.py」「数据可视化.py」「模型预测.py」按流程拆开还留了house.csv、house-info.csv这类中间数据方便你对照每一步的输入输出。适合谁刚学完 Python 基础、想找一个能写进简历的完整项目练手的人也适合做数据分析的从业者想看看二手房字段总价、单价、建筑面积、建筑年代、楼层、朝向、装修程度到底怎么和房价预测模型串起来。下面我按「资源是什么 → 怎么用 → 坑在哪」的顺序把这份包拆开讲透。2. 爬虫层拆解随机请求头、URL 队列与字段落库2.1 为什么这套爬虫要单独写一个「随机请求头」脚本房天下这类房产站点对高频访问的识别主要看两点请求头特征和访问节奏。项目里把请求头逻辑单独抽成爬虫-随机请求头.py思路是维护一个 User-Agent 池每次请求随机取一个配合urls.txt、urls2.txt两个 URL 队列文件做分页抓取。常见做法是用requests发请求、BeautifulSoup或lxml解析列表页再把详情页字段拼成一条记录。这里的关键不是代码多复杂而是把「请求头」和「URL 管理」解耦——你换站点时只改 URL 生成逻辑请求头池不用动。import requests import random import time # 随机请求头池覆盖主流浏览器降低被识别为脚本的概率 USER_AGENTS [ Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0 Safari/537.36, Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15, Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0, ] def fetch(url): headers { User-Agent: random.choice(USER_AGENTS), Accept-Language: zh-CN,zh;q0.9, } # 每次请求之间随机停顿避免固定间隔被识别 time.sleep(random.uniform(1.5, 4.0)) resp requests.get(url, headersheaders, timeout10) resp.encoding resp.apparent_encoding # 房天下页面编码不固定交给 apparent_encoding 判断 return resp.text逻辑说明random.choice每次从池里挑一个 UAtime.sleep用 1.54 秒的随机区间模拟人工浏览节奏。参数上timeout10是防止某个请求卡死拖垮整批任务apparent_encoding比写死utf-8稳因为房产站点部分页面是 GBK。如果你把停顿改成固定 1 秒跑几百条后大概率触发限流这是血泪经验。2.2 URL 队列与分页参数怎么设项目里urls.txt和urls2.txt存的是待抓取的列表页地址house001.py、house002.py、house003.py是不同阶段的爬虫版本。分页通常靠 URL 里的page参数递增比如.../house/pg{page}/。我一般会把「页码范围」和「区域筛选」做成两个变量先小范围跑 23 页验证字段解析对不对再放开全量。字段落库用pandas直接写 CSV对应包里的house.csv、house-info.csv、house-test1.csv等中间产物。import pandas as pd def parse_list(html): # 伪代码结构真实解析依赖具体 DOM这里示意字段组织方式 records [] for item in soup.select(.list-item): records.append({ title: item.select_one(.title).text.strip(), total_price: item.select_one(.total).text.strip(), # 总价单位万元 unit_price: item.select_one(.unit).text.strip(), # 单价元/平米 area: item.select_one(.area).text.strip(), # 建筑面积 region: item.select_one(.region).text.strip(), # 行政区域 }) return records df pd.DataFrame(all_records) df.to_csv(house.csv, indexFalse, encodingutf-8-sig) # utf-8-sig 防止 Excel 打开乱码参数说明encodingutf-8-sig是给 Excel 用的带 BOM 头中文才不乱码indexFalse避免多出一列索引。字段命名要和后续清洗脚本对齐否则数据清洗.py里改列名会多一步。这里提醒一句抓取频率和并发别贪单机串行加随机停顿是最稳的分布式爬虫在这个体量下没必要。3. 数据清洗与可视化把 31 张图背后的字段关系理清3.1 数据清洗.py 到底洗了什么二手房原始数据脏在三处总价带「万」字、面积带「平米」、楼层和朝向是文本描述。数据清洗.py的核心工作就是把这些转成数值型再处理缺失和异常。常见做法是用正则抽数字apply到整列再用pd.to_numeric兜底。项目里7.6-test3-数据清洗.py是清洗阶段的迭代版本说明作者也是反复调过的。import re import pandas as pd df pd.read_csv(house.csv) def to_number(x): if pd.isna(x): return None m re.search(r(\d\.?\d*), str(x)) # 抽出第一个数字 return float(m.group(1)) if m else None # 总价、单价、面积统一转数值 for col in [total_price, unit_price, area]: df[col] df[col].apply(to_number) # 建筑面积异常值处理小于 10 平米或大于 1000 平米的按缺失处理 df.loc[(df[area] 10) | (df[area] 1000), area] None # 按总价中位数填充缺失比均值抗极端值 df[total_price] df[total_price].fillna(df[total_price].median()) df.to_csv(house_clean.csv, indexFalse, encodingutf-8-sig)逻辑说明正则(\d\.?\d*)能同时匹配整数和小数异常值用区间卡掉而不是直接删行是为了保留其他字段信息。填充用中位数而非均值因为房价分布右偏均值会被高价房源拉高。这一步做完house_clean.csv才能喂给可视化脚本。3.2 31 张 PNG 图表分别在看什么关系包里的图表文件名本身就是一份分析清单我按字段关系归了个类方便你对照数据可视化.py复现图表主题涉及字段能看出什么年份与总价关系图建筑年代、总价房龄对价格的衰减趋势箱线图 / 箱线图分析-总价-建筑面积总价、建筑面积面积区间的价格离散度与离群点探究单价、数量、总价和行政区域之间的关系单价、总价、区域各区域价格梯队探究建筑结构和总价的关系建筑结构、总价板楼/塔楼的价格差异探究装修程度和总价的关系装修程度、总价精装与毛坯的溢价探究楼层和总价的关系楼层、总价中高楼层是否更贵探究朝向和总价的关系朝向、总价南北通透的溢价探究户型和总价的关系户型、总价几室几厅的主流价格带探究电梯和总价的关系电梯、总价有无电梯的价格分界探究产权性质和总价的关系产权性质、总价商品房与经适房差异探究住宅类别和总价的关系住宅类别、总价普通住宅与别墅差异探究建筑形式和总价的关系建筑形式、总价不同建筑形态价格分布用matplotlib或seaborn画箱线图时plt.rcParams[font.sans-serif] [SimHei]是中文显示的关键不加就是一堆方框。数据可视化.py里应该做了这个设置你复现时先确认字体否则 31 张图全变乱码。4. 房价预测模型从特征工程到模型预测.py 的落地4.1 特征怎么选、类别变量怎么编码模型预测.py和预测.py、预测价格.py是建模阶段的核心。二手房数据里既有数值特征面积、房龄、单价也有类别特征区域、朝向、装修、楼层。常见做法是数值特征直接进模型类别特征做独热编码或标签编码。区域这种高基数类别独热会让维度爆炸我一般用目标编码或直接按区域均价映射成一个数值特征。import pandas as pd from sklearn.model_selection import train_test_split from sklearn.ensemble import RandomForestRegressor from sklearn.metrics import mean_absolute_error, r2_score df pd.read_csv(house_clean.csv) # 类别特征独热编码drop_first 避免共线性 df pd.get_dummies(df, columns[region, orientation, decoration], drop_firstTrue) # 特征与标签拆分 X df.drop(columns[total_price, title], errorsignore) y df[total_price] X_train, X_test, y_train, y_test train_test_split(X, y, test_size0.2, random_state42) model RandomForestRegressor(n_estimators200, max_depth12, random_state42) model.fit(X_train, y_train) pred model.predict(X_test) print(MAE:, mean_absolute_error(y_test, pred)) print(R2:, r2_score(y_test, pred))参数说明n_estimators200是树的数量太少欠拟合、太多训练慢max_depth12限制树深防过拟合random_state42保证结果可复现。评估用 MAE 和 R2MAE 直接反映预测总价平均差多少万元比 MSE 好解释。如果 R2 低于 0.6先回头查清洗阶段有没有把关键字段洗丢。4.2 训练集和测试集怎么切才不骗自己house-test1.csv、house-test2.csv、df-test3.csv这些文件说明作者留了独立测试数据。血泪经验是别用同一批数据既训练又评估R2 会虚高。正确做法是train_test_split切 8:2或者按时间切——用早期房源训练、近期房源测试更接近真实预测场景。如果数据量够交叉验证比单次切分稳cross_val_score一行就能跑。5. 避坑与排查这套源码跑不起来时先看这几条5.1 请求头随机了还是被封现象跑几十条后返回 403 或验证码页。原因随机 UA 只解决了请求头特征访问频率和 IP 维度没变。解决把time.sleep区间拉大到 36 秒单次任务控制在几百条以内分批次跑别一口气抓几千页。5.2 中文图表全是方框现象数据可视化.py生成的 PNG 里中文变方块。原因matplotlib默认字体不含中文。解决在脚本开头加plt.rcParams[font.sans-serif] [SimHei]和plt.rcParams[axes.unicode_minus] False前者管中文后者管负号显示。5.3 CSV 用 Excel 打开乱码现象house.csv双击打开中文乱码。原因默认utf-8不带 BOMExcel 按 GBK 解析。解决写文件时统一用encodingutf-8-sig读的时候用encodingutf-8即可。5.4 模型 R2 高得离谱现象训练集 R2 0.95测试集掉到 0.4。原因数据泄漏比如把「单价」当特征去预测「总价」而单价本身就是总价除以面积算出来的。解决检查特征列凡是和标签有直接算术关系的字段一律剔除unit_price必须从特征里拿掉。5.5 清洗后样本量骤减现象清洗完house_clean.csv只剩几百行。原因异常值区间卡太狠或者dropna把含缺失的行全删了。解决异常值按缺失处理而非删行缺失用中位数或众数填充先看每列缺失比例再决定策略别无脑dropna。6. 进阶玩法把预测脚本包成可复用工具的两个技巧第一个技巧是特征工程函数化。模型预测.py里如果把编码、异常处理写死在主流程换个数据集就得重写。我一般抽一个build_features(df)函数输入原始 DataFrame、输出特征矩阵训练和预测共用同一套逻辑避免线上线下特征不一致——这是模型上线翻车最常见的原因。第二个技巧是模型持久化用joblib把训练好的模型存下来预测时直接加载不用每次重训。import joblib # 训练完保存 joblib.dump(model, house_price_model.pkl) # 预测时加载 model joblib.load(house_price_model.pkl) new_pred model.predict(new_X)参数上joblib比pickle更适合存 sklearn 模型内部对 numpy 数组有优化大模型读写更快。验证方法很简单存完再加载对同一批测试数据预测结果应完全一致不一致说明特征处理有随机性没固定random_state。另外scoring.py这个文件名暗示作者可能做过模型打分对比你可以在此基础上加一个多模型对比循环把随机森林、梯度提升、线性回归的 MAE 拉一张表选最优的再持久化。从那以后我每次拿到这种实训源码包都强制先跑一遍「爬虫小样本 → 清洗 → 单图可视化 → 单模型」的最小闭环确认链路通了再放开全量不然中途某个环节报错你连是哪一步的问题都定位不到。这套包的价值不在于代码多精妙而在于它把完整流程的每一步都留了文件痕迹你顺着文件名就能还原作者的思路。希望帮到你。本文还有配套的精品资源点击获取
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。