Python二手房数据爬取与可视化分析:毕业设计实战指南 简介本资源是一套完整的本科毕业设计实战项目面向计算机及相关专业学生解决二手房数据获取难、分析流程不清晰、可视化呈现薄弱等课程实践痛点。项目涵盖网络爬虫、数据清洗、统计分析与多维可视化全流程代码经本地编译调试可直接运行配套PPT答辩文档结构规范、逻辑严谨已通过导师评审获98分高分。压缩包共156个文件40.03MB含18个核心Python脚本爬取、清洗、分析、18个CSV数据集原始与清洗后多版本、65张可视化PNG图表、15个HTML交互报告及JS前端支持文件另有配置文件与说明文本目录层级分明便于按模块学习与复用。目前已有139人下载学习适合毕业设计选题参考、课程大作业开发或数据分析能力进阶训练提供从数据采集到成果展示的端到端可执行方案。1. 项目概述与核心价值最近几年无论是计算机、软件工程还是数据科学相关专业的同学在毕业设计选题上一个明显的趋势是越来越“务实”。大家不再满足于做一个简单的管理系统或者玩具Demo而是希望自己的作品能解决一个真实世界的问题最好还能用上点“时髦”的技术栈。于是“数据爬取可视化分析”这个组合拳就成了毕业设计里的常青树尤其是结合了像二手房市场这样贴近生活、数据源丰富且分析价值高的场景。这个项目说白了就是教你如何用Python这门“瑞士军刀”从零到一构建一个完整的、能跑通的数据分析项目最终产出一份能拿得出手的毕业设计附带源码、报告和PPT。为什么这个选题经久不衰因为它完美契合了毕业设计的几个核心要求技术综合性、问题现实性、成果可展示性。你需要用到网络爬虫技术去获取原始数据这考验了你对HTTP协议、网页结构解析、反爬策略应对的理解接着你需要对爬下来的“脏数据”进行清洗、整理、存储这涉及数据预处理和数据库或文件操作最后通过可视化图表将分析结果直观地呈现出来这又考验了你对数据分析库和绘图库的掌握。整个过程就是一个微缩版的真实数据工程与数据分析流程。对于招聘方而言这样一个完整的项目经历远比你在简历上罗列一堆孤立的技能点要有说服力得多。接下来我将以一个过来人的视角为你拆解这个项目的完整实现路径。我会假设你是一个有一定Python基础但对爬虫和数据分析实战经验不多的同学。我们将从设计思路、技术选型、核心实现、避坑指南到报告与PPT的撰写要点一步步把这件事讲透。目标不仅是让你能复现这个项目更是让你理解每一步背后的“为什么”从而具备举一反三的能力。2. 项目整体设计与技术栈选型在动手写第一行代码之前花点时间把整体架构想清楚能省去后面无数返工的麻烦。一个健壮的二手房数据分析项目通常遵循“数据采集 - 数据存储 - 数据清洗 - 数据分析 - 数据可视化”的流水线。我们的技术选型也需要围绕这条流水线展开。2.1 核心架构与流程设计整个项目的核心工作流可以抽象为以下几个阶段目标确定与网站分析明确你要爬取哪个城市的二手房数据例如北京、上海、深圳并选定1-2个主流房产信息平台如链家、贝壳、安居客等作为数据源。这一步的关键是手动分析目标网站的页面结构、URL规律以及潜在的反爬机制。爬虫程序开发编写Python脚本模拟浏览器请求解析网页HTML提取出所需的字段如标题、总价、单价、面积、户型、楼层、朝向、小区、区域、挂牌时间等。数据持久化将爬取到的结构化数据保存起来。对于毕业设计级别数据量通常在几千到几万条选择轻量级的CSV文件或SQLite数据库就完全足够便于管理和后续分析。数据清洗与预处理原始数据必然存在缺失值、异常值、格式不一致等问题例如价格单位不统一、面积包含非数字字符。这一步是保证分析结果可信度的基石。数据分析与可视化基于清洗后的数据提出具体的分析问题并利用图表进行解答。例如各区域房价分布对比、单价与面积的关系、不同户型的平均总价等。成果封装与报告撰写将代码模块化整理成清晰的工程结构将分析过程和结论系统地整理成毕业设计报告和答辩PPT。2.2 关键技术栈选型与理由为什么是Python因为它在数据抓取、处理、分析、可视化这一整条链上拥有最成熟、最丰富的生态系统。下面是我们将用到的核心库及其选型理由爬虫核心库Requests BeautifulSoup4 / lxml / PyQueryRequests人性化的HTTP库用于发送网络请求获取网页HTML内容。比Python内置的urllib更简洁易用。BeautifulSoup4 (bs4)HTML/XML解析库语法接近自然语言学习曲线平缓非常适合初学者快速提取数据。对于复杂的页面或需要高性能解析时可以搭配lxml作为解析后端。PyQuery语法类似jQuery对于前端熟悉的同学可能更顺手。本项目以bs4为例进行讲解。选型理由这个组合是入门级爬虫的黄金搭档资料丰富社区活跃足以应对大多数静态网页的数据抓取需求。数据存储Pandas SQLite / CSVPandas这不是一个简单的库它是Python数据分析的基石。它提供的DataFrame数据结构可以让你像操作Excel表格一样轻松地处理数据清洗、过滤、分组、聚合、合并等。SQLite轻量级、无服务器的文件数据库。你可以通过Pandas直接读写SQLite也可以使用Python内置的sqlite3模块。它免去了安装配置大型数据库如MySQL的麻烦一个.db文件搞定一切。CSV纯文本格式通用性极强。Pandas可以非常方便地读写CSV。对于数据量不大且不需要复杂查询的场景CSV是最简单的选择。选型理由Pandas是事实上的标准必须用。存储方案上我强烈建议在爬虫阶段直接存入SQLite在分析阶段用Pandas从SQLite中读取。这样既利用了数据库的结构化存储优势便于管理多批次爬取的数据又享受了Pandas强大的分析能力。数据可视化Matplotlib SeabornMatplotlibPython绘图库的“老祖宗”功能强大且灵活几乎能绘制任何类型的静态图表。但默认样式较为朴素需要一定配置才能达到出版级水准。Seaborn基于Matplotlib的高级统计图表库。它提供了更美观的默认样式和更简洁的高级接口特别适合用于统计数据的可视化如分布图、关系图、分类图等。它和Pandas的DataFrame结合得非常好。选型理由Matplotlib是基础必须了解。Seaborn能让你用更少的代码画出更专业的图表极大提升效率和质量。两者结合足以覆盖毕业设计所需的所有图表类型。辅助工具库Fake-UserAgent随机生成User-Agent请求头是绕过基于请求头反爬的最基本手段。Time / Random用于在请求间插入随机延时模拟人类操作避免请求过快被网站封禁IP。Re (正则表达式)在解析文本字段如从“建筑面积89.5平米”中提取数字89.5时非常有用。注意关于反爬与道德法律边界爬虫工程师必须遵守robots.txt协议网站根目录下的一个文本文件声明了哪些页面允许爬取。在开发前务必检查目标网站的robots.txt。同时我们的爬虫应仅限于个人学习、毕业设计研究使用绝对禁止将爬取的数据用于商业用途或对目标网站造成明显压力如高频并发请求。在代码中合理设置延时例如time.sleep(random.uniform(1, 3))是基本的职业操守。3. 核心模块一二手房数据爬虫实现详解这是项目的基石也是最容易出问题的环节。我们将以一个典型的房产网站列表页-详情页结构为例讲解一个稳健爬虫的构建过程。3.1 网页结构分析与URL策略首先你需要手动打开目标网站比如链家北京的二手房列表页。观察URL的变化规律。通常列表页的URL会包含区域、页码等参数。例如https://bj.lianjia.com/ershoufang/pg2/表示北京二手房第二页。https://bj.lianjia.com/ershoufang/pg3rs海淀/表示北京海淀区二手房第三页。策略我们可以通过构造一个基础URL模板循环页码来遍历所有列表页。对于分区爬取则在外层再循环区域参数。关键步骤使用浏览器开发者工具F12切换到Network网络选项卡刷新页面查看浏览器发送了哪些请求找到真正返回房源列表数据的请求。有时数据可能通过Ajax加载返回的是JSON格式那会更简单直接解析JSON。我们假设是最常见的静态HTML页面。在Elements元素选项卡中使用检查工具箭头图标点击页面上的一个房源标题、价格等信息找到这些信息在HTML代码中对应的标签和CSS选择器路径。3.2 爬虫代码实现步骤假设我们确定了数据在静态HTML中下面是一个高度概括但结构清晰的爬虫实现框架import requests from bs4 import BeautifulSoup import pandas as pd import sqlite3 import time import random from fake_useragent import UserAgent class LianJiaSpider: def __init__(self, base_url, db_pathershoufang.db): self.base_url base_url # 列表页基础URL如 https://bj.lianjia.com/ershoufang/pg{} self.ua UserAgent() self.db_path db_path self.init_database() def init_database(self): 初始化SQLite数据库和表结构 conn sqlite3.connect(self.db_path) cursor conn.cursor() cursor.execute( CREATE TABLE IF NOT EXISTS houses ( id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT, total_price REAL, unit_price REAL, area REAL, layout TEXT, floor TEXT, orientation TEXT, community TEXT, district TEXT, list_date TEXT, crawl_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) ) conn.commit() conn.close() def get_page(self, page_num): 获取指定页码的HTML内容 url self.base_url.format(page_num) headers {User-Agent: self.ua.random} try: # 添加随机延时尊重网站 time.sleep(random.uniform(1, 2)) response requests.get(url, headersheaders, timeout10) response.raise_for_status() # 检查请求是否成功 response.encoding utf-8 # 根据网站实际情况调整编码 return response.text except requests.RequestException as e: print(f请求第{page_num}页失败: {e}) return None def parse_list_page(self, html): 解析列表页获取所有房源详情页链接 soup BeautifulSoup(html, lxml) # 使用开发者工具找到的CSS选择器这里是一个示例实际需要你自行分析 house_links [] for item in soup.select(.sellListContent li .title a): link item.get(href) if link and link.startswith(https): house_links.append(link) return house_links def parse_detail_page(self, url): 解析单个房源详情页提取具体信息 html self.get_page(url) # 复用get_page方法但注意详情页URL是直接的 if not html: return None soup BeautifulSoup(html, lxml) house_info {} # 以下是示例解析逻辑每个字段的选择器都需要你根据实际网页结构调整 try: house_info[title] soup.select_one(.main .title h1).text.strip() # 总价可能包含“万”字需要处理 total_price_text soup.select_one(.total).text.strip() house_info[total_price] float(total_price_text.replace(万, )) # 单价可能包含“元/平米”等字符 unit_price_text soup.select_one(.unitPriceValue).text.strip() house_info[unit_price] float(unit_price_text.replace(元/平米, ).replace(,, )) # 面积 area_text soup.select_one(.area .mainInfo).text.strip() house_info[area] float(area_text.replace(平米, )) # 户型、楼层、朝向等信息通常在某个信息栏用循环提取 for info in soup.select(.base .content li): text info.text if 房屋户型 in text: house_info[layout] text.split()[-1] elif 所在楼层 in text: house_info[floor] text.split()[-1] elif 房屋朝向 in text: house_info[orientation] text.split()[-1] # 小区和区域 house_info[community] soup.select_one(.communityName a).text.strip() house_info[district] soup.select_one(.areaName .info a).text.strip() # 挂牌时间 house_info[list_date] soup.select_one(.transaction .content li:nth-child(1) span:nth-child(2)).text.strip() except AttributeError as e: # 如果某个元素没找到记录错误并跳过该字段 print(f解析详情页 {url} 时出错: {e}可能页面结构有变化) return None return house_info def save_to_db(self, house_info): 将一条房源信息保存到数据库 if not house_info: return conn sqlite3.connect(self.db_path) df pd.DataFrame([house_info]) # 将单条数据转为DataFrame # 使用pandas的to_sql方法如果表存在则追加 df.to_sql(houses, conn, if_existsappend, indexFalse) conn.close() def run(self, start_page1, end_page10): 主运行函数控制爬取流程 for page in range(start_page, end_page 1): print(f正在爬取第 {page} 页...) list_html self.get_page(page) if not list_html: continue detail_urls self.parse_list_page(list_html) for url in detail_urls: info self.parse_detail_page(url) self.save_to_db(info) print(f已保存: {info.get(title, N/A)}) print(f第 {page} 页爬取完成。) if __name__ __main__: # 示例爬取北京二手房前5页数据 base_url https://bj.lianjia.com/ershoufang/pg{} spider LianJiaSpider(base_url) spider.run(start_page1, end_page5)实操心得与避坑指南选择器稳定性网站前端可能改版你写的CSS选择器可能会失效。尽量选择那些具有唯一性、语义化且不太可能频繁变动的class或id。避免使用依赖于具体位置如div:nth-child(5)的选择器。异常处理至关重要网络请求可能超时、页面结构可能变化、数据可能缺失。代码中必须用try...except包裹核心解析逻辑并记录错误日志确保程序不会因为单条数据解析失败而崩溃。控制爬取速度time.sleep(random.uniform(1, 3))这样的随机延时是必须的。过于频繁的请求可能导致你的IP被暂时封禁。对于毕业设计慢一点没关系稳定拿到数据才是关键。数据去重在保存到数据库前可以检查该房源URL或唯一ID是否已存在避免重复数据。可以在数据库表中为url字段添加UNIQUE约束或在插入前进行查询。增量爬取更高级的做法是记录爬取时间下次只爬取新上架或更新的房源。这需要网站页面支持按时间排序并且你的数据库设计要能区分新旧数据。4. 核心模块二数据清洗与预处理实战爬虫拿到的数据是“原始”的直接用于分析会产生大量错误。数据清洗通常要花费整个项目40%以上的时间。我们将使用Pandas来完成这项繁琐但关键的工作。4.1 数据加载与初步探查首先将SQLite中的数据读入Pandas的DataFrame。import pandas as pd import sqlite3 import numpy as np # 连接数据库读取数据 conn sqlite3.connect(ershoufang.db) df pd.read_sql_query(SELECT * FROM houses, conn) conn.close() # 查看数据概览 print(f数据形状: {df.shape}) # (行数 列数) print(df.info()) # 查看每列的数据类型和非空值数量 print(df.head()) # 查看前几行数据 print(df.describe()) # 对数值列进行统计描述均值、标准差、分位数等通过df.info()你可以立刻发现哪些列存在大量缺失值Non-Null Count远小于总行数。通过df.describe()可以快速发现数值列的异常情况比如单价为0或面积大到离谱。4.2 典型脏数据处理方法处理缺失值删除如果某一行关键字段如总价、面积缺失或者缺失行数占比较小可以直接删除df_clean df.dropna(subset[total_price, area])。填充对于数值列可以用中位数或均值填充中位数对异常值不敏感更稳健df[unit_price].fillna(df[unit_price].median(), inplaceTrue)。对于分类列如朝向可以用众数填充或单独设为“未知”。处理异常值基于业务常识单价低于5000元/平米或高于20万元/平米根据城市设定阈值的很可能是错误数据或特殊房源如车位。面积小于10平米或大于500平米的也需要审视。统计方法使用箱线图IQR原则识别异常值。但需谨慎二手房市场本身就有豪宅和极小户型它们不一定是“错误”可能是分析时需要单独考虑的类别。# 示例过滤掉单价异常的数据假设我们研究普通住宅 Q1 df[unit_price].quantile(0.25) Q3 df[unit_price].quantile(0.75) IQR Q3 - Q1 lower_bound Q1 - 1.5 * IQR upper_bound Q3 1.5 * IQR # 可以选择查看异常值或直接过滤 outliers df[(df[unit_price] lower_bound) | (df[unit_price] upper_bound)] df_clean df[(df[unit_price] lower_bound) (df[unit_price] upper_bound)].copy()格式标准化字符串处理去除首尾空格df[district] df[district].str.strip()。统一字符df[orientation] df[orientation].replace({南: 朝南, 北: 朝北})。数值提取如果面积字段是“89.5平米”需要提取数字df[area] df[area].str.extract((\d\.?\d*)).astype(float)。这里用到了正则表达式。类型转换确保数值列是float或int类型日期列是datetime类型df[list_date] pd.to_datetime(df[list_date], errorscoerce)。数据衍生创建新特征往往能提升分析深度。例如计算“房龄”如果数据中有建筑年代df[house_age] pd.datetime.now().year - df[build_year]。根据总价和面积可以反向验证单价是否一致df[calculated_unit_price] df[total_price] * 10000 / df[area]并与爬取的unit_price对比排查数据错误。清洗流程建议将清洗步骤封装成函数形成一个可复用的清洗管道Pipeline。这样代码清晰也便于调整清洗逻辑。def clean_data(df): df_clean df.copy() # 1. 删除关键字段缺失的行 df_clean df_clean.dropna(subset[total_price, area, unit_price]) # 2. 格式化面积和单价 df_clean[area] pd.to_numeric(df_clean[area], errorscoerce) df_clean[unit_price] pd.to_numeric(df_clean[unit_price], errorscoerce) # 3. 删除面积或单价为0或负数的行 df_clean df_clean[(df_clean[area] 10) (df_clean[unit_price] 1000)] # 4. 处理朝向缺失值 df_clean[orientation] df_clean[orientation].fillna(未知) # 5. 去除字符串字段空格 text_cols [title, layout, floor, orientation, community, district] for col in text_cols: if col in df_clean.columns: df_clean[col] df_clean[col].astype(str).str.strip() # 6. 重置索引 df_clean.reset_index(dropTrue, inplaceTrue) return df_clean df_cleaned clean_data(df) print(f清洗后数据形状: {df_cleaned.shape})5. 核心模块三数据分析与可视化呈现数据清洗完毕后就进入了最有趣的部分——从数据中发现故事。可视化是讲好故事的关键。我们使用Matplotlib和Seaborn来制作图表。5.1 分析维度与可视化图表选型在画图之前先想清楚你要回答什么问题。以下是一些经典的分析方向及对应的可视化方案整体分布与概况问题房价的整体分布情况如何哪个价格区间的房子最多图表直方图Histogram、核密度估计图KDE Plot。代码示例Seabornimport seaborn as sns import matplotlib.pyplot as plt plt.figure(figsize(12, 5)) plt.subplot(1, 2, 1) sns.histplot(datadf_cleaned, xtotal_price, bins30, kdeTrue) plt.title(总价分布直方图) plt.xlabel(总价万元) plt.subplot(1, 2, 2) sns.histplot(datadf_cleaned, xunit_price, bins30, kdeTrue, colororange) plt.title(单价分布直方图) plt.xlabel(单价元/平米) plt.tight_layout() plt.show()区域对比问题哪个区的平均房价最高各区的房源数量分布如何图表柱状图Bar Plot用于比较均值、箱线图Box Plot用于比较分布且展示异常值、计数图Count Plot。代码示例# 按区域计算平均单价 district_avg_price df_cleaned.groupby(district)[unit_price].mean().sort_values(ascendingFalse) plt.figure(figsize(10, 6)) district_avg_price.plot(kindbar) plt.title(各区域二手房平均单价对比) plt.ylabel(平均单价元/平米) plt.xticks(rotation45) plt.tight_layout() plt.show() # 使用箱线图查看各区域单价分布 plt.figure(figsize(14, 6)) # 为了图形清晰可以只选取房源数量较多的前10个区域 top_districts df_cleaned[district].value_counts().head(10).index df_top df_cleaned[df_cleaned[district].isin(top_districts)] sns.boxplot(datadf_top, xdistrict, yunit_price) plt.title(主要区域二手房单价分布箱线图) plt.xticks(rotation45) plt.tight_layout() plt.show()属性关系探索问题房屋单价和面积有关系吗总价和面积呢不同朝向的房价有差异吗图表散点图Scatter Plot看两个连续变量的关系、分类散点图Swarm Plot / Stripplot或小提琴图Violin Plot看分类变量与连续变量的关系。代码示例# 单价 vs 面积 散点图 plt.figure(figsize(8, 6)) sns.scatterplot(datadf_cleaned, xarea, yunit_price, alpha0.5) plt.title(房屋面积与单价关系散点图) plt.xlabel(面积平米) plt.ylabel(单价元/平米) plt.show() # 不同朝向的单价分布小提琴图 plt.figure(figsize(10, 6)) # 筛选出主要的几种朝向 major_orientations [朝南, 朝北, 朝东, 朝西, 南北通透] df_orient df_cleaned[df_cleaned[orientation].isin(major_orientations)] sns.violinplot(datadf_orient, xorientation, yunit_price) plt.title(不同朝向二手房单价分布) plt.xlabel(朝向) plt.ylabel(单价元/平米) plt.tight_layout() plt.show()趋势分析问题挂牌价格随时间有变化趋势吗如果爬取了挂牌时间图表折线图Line Plot。代码示例# 假设有 list_date 字段且已转换为 datetime 类型 df_cleaned[month] df_cleaned[list_date].dt.to_period(M) # 按月份聚合 monthly_avg_price df_cleaned.groupby(month)[unit_price].mean() monthly_avg_price.plot(kindline, markero, figsize(12, 5)) plt.title(月度平均挂牌单价趋势) plt.xlabel(月份) plt.ylabel(平均单价元/平米) plt.grid(True) plt.tight_layout() plt.show()5.2 可视化进阶技巧与报告整合图表美化Seaborn有内置主题sns.set_theme()可以设置整体风格。使用plt.figure(figsize(width, height))控制图形大小。为图表添加清晰的标题plt.title()和轴标签plt.xlabel(),plt.ylabel()。使用plt.tight_layout()自动调整子图间距。保存图表在生成图表后使用plt.savefig(output.png, dpi300, bbox_inchestight)将图表保存为高分辨率图片便于插入毕业设计报告和PPT中。分析结论每张图表下面都应该用文字简要描述你观察到了什么。例如“从区域均价柱状图可以看出XX区的平均单价显著高于其他区域可能是由于其核心商圈和优质学区资源。” 将图表和文字分析结合形成完整的分析段落。6. 毕业设计报告与PPT撰写核心要点代码和分析完成后如何将它们组织成一份合格的毕业设计文档和答辩PPT是临门一脚。6.1 毕业设计报告结构建议报告不应是代码的堆砌而是一个有逻辑的论述过程。建议结构如下摘要用200-300字概括整个项目包括背景、目标、采用的技术方法、主要分析过程和最终结论。绪论/引言阐述选题背景二手房市场的重要性、数据分析的价值、国内外研究现状简要提及相关技术应用、本项目的研究目标和意义。相关技术与理论介绍本项目用到的核心技术原理如Python爬虫原理Requests/BeautifulSoup、数据分析流程Pandas、可视化方法Matplotlib/Seaborn等。这部分是体现你理论深度的地方不要只写库怎么用要写一点背后的原理。系统设计与实现这是核心章节。总体设计画出系统架构图可以用PPT画了贴进来说明数据流。数据采集模块详细设计详细说明爬虫策略、反爬应对、数据存储设计ER图或表结构。数据处理模块详细设计说明数据清洗的流程、规则和方法。数据分析与可视化模块详细设计阐述你选择的分析维度和可视化图表类型的理由。系统测试与结果分析测试说明如何测试爬虫的稳定性如不同时间点运行、数据清洗的正确性。结果展示与分析将第5部分生成的核心图表贴进来并配上详细的分析文字。这是报告最出彩的部分要层层深入有数据支撑的结论。总结与展望总结项目完成的工作、取得的成果、遇到的难点及解决方案。客观说明本项目的局限性如数据量、爬取网站单一、分析维度有限等并提出可能的改进方向如引入机器学习进行房价预测、爬取多源数据对比、构建实时监控系统等。参考文献规范引用你参考的博客、书籍、技术文档等。附录可以放核心源代码不必全部放关键部分、完整的数据库表结构等。6.2 答辩PPT制作心法PPT是辅助你演讲的工具切忌大段文字。结构清晰封面、目录、选题背景与意义、技术路线与系统设计、核心实现与难点突破、数据分析结果与发现、总结与展望、致谢。图文并茂图表说话多放可视化结果图表少放文字和代码。一页PPT讲清楚一个点。代码如果需要展示只放最关键的那几行并配上解释。突出亮点将项目中最有技术含量如巧妙的反爬处理或最有价值的发现如某个颠覆常识的数据结论重点展示。演练讲稿为每一页PPT准备口头阐述内容控制好时间通常答辩10-15分钟。重点讲“我做了什么”、“为什么这么做”、“结果是什么”、“体现了什么能力或发现”。准备问答提前思考老师可能会问的问题如“如果网站结构变了怎么办”、“你的数据清洗规则科学依据是什么”、“这个分析结论有什么实际应用价值”。7. 常见问题排查与项目优化建议在实际操作中你几乎一定会遇到下面这些问题。7.1 爬虫阶段常见问题问题1返回403 Forbidden错误原因网站识别出你是爬虫程序。最常见的反爬手段就是检查User-Agent。解决使用fake-useragent库随机生成浏览器UA。此外检查是否需要携带Cookie有时需要先访问首页获取Cookie、Referer等请求头。对于更复杂的反爬可能需要使用Selenium模拟浏览器但会极大降低效率。问题2解析不到数据soup.select()返回空列表原因网页是动态加载的Ajax你下载的初始HTML不包含数据或者你的CSS选择器写错了。解决首先在浏览器中“查看网页源代码”搜索一下你想抓取的关键词如房价数字如果源码里没有说明是动态加载。此时需要在Network选项卡中寻找XHR/Fetch请求找到返回真实数据的API接口通常是JSON格式直接请求这个接口会更简单。如果源码里有那就是选择器问题重新用开发者工具仔细定位元素。问题3爬着爬着就被封IP了原因请求频率太高。解决增加请求间隔时间time.sleep并加入随机性random.uniform。可以考虑使用代理IP池但对于毕业设计来说控制频率通常足够。问题4数据保存时出现编码错误原因网页编码和Python处理编码不一致或者数据库/文件编码设置问题。解决确保response.encoding设置正确通常是utf-8。保存到CSV或数据库时也指定encodingutf-8-sigCSV或确保数据库连接使用UTF-8。7.2 数据分析与可视化常见问题问题1图表显示中文乱码解决这是Matplotlib的经典问题。需要在绘图前设置中文字体。import matplotlib.pyplot as plt plt.rcParams[font.sans-serif] [SimHei] # 用来正常显示中文标签 plt.rcParams[axes.unicode_minus] False # 用来正常显示负号如果系统没有SimHei黑体可以指定其他已安装的中文字体路径。问题2数据量太大散点图重叠严重看不清解决使用alpha参数设置透明度sns.scatterplot(..., alpha0.2)或者使用二维核密度图sns.kdeplot来表现分布密度。也可以进行抽样显示。问题3分组太多柱状图或箱线图x轴标签重叠解决使用plt.xticks(rotation45)旋转标签。或者只展示主要类别如前N个其他归为“其他”。7.3 项目进阶优化方向如果你的目标是拿到优秀毕业设计可以考虑以下优化点爬虫工程化将爬虫拆分为调度器、下载器、解析器、存储器等模块使用Scrapy框架重构。这能让你更深入地理解爬虫框架的设计思想。数据存储升级使用更正式的数据库如MySQL或PostgreSQL并设计更规范的表结构建立索引以提升查询效率。分析深度加强引入简单的机器学习模型。例如使用scikit-learn库以面积、区域、楼层、朝向等为特征尝试构建一个房价预测的线性回归模型。这能极大提升项目的技术含量。交互式可视化使用Plotly或PyEcharts库生成可交互的网页图表将其整合到一个简单的Flask或Streamlit网页应用中让分析结果更具表现力。部署与自动化将爬虫脚本部署到云服务器使用crontab或APScheduler设置定时任务实现数据的自动定时爬取和更新。这个项目就像一把钥匙帮你打开了用Python解决实际数据问题的大门。从遇到第一个反爬问题时的抓耳挠腮到最终看到清晰图表揭示出数据规律的豁然开朗整个过程收获的绝不仅仅是一个毕业设计。最重要的是你拥有了一个从需求分析、技术攻关到成果展示的完整项目经验这才是你简历上最硬核的一笔。本文还有配套的精品资源点击获取

相关新闻

最新新闻

嵌入式实战:STM32家居环境监测系统全链路解析与工程实践

嵌入式实战:STM32家居环境监测系统全链路解析与工程实践

先说结论:这个 STM32 家居环境监测系统,最值得看的不是“STM32”这三个字,而是它把采集、显示、报警、源码、原理图全部串成了一条完整链路。如果你正在找嵌入式课程设计、毕业设计,或者刚把 STM32 基础外设学完、想做一个能真正上…

2026/9/3 3:14:48
电竞复盘技术解析:从《英雄联盟》职业比赛到个人游戏理解的深度分析方法

电竞复盘技术解析:从《英雄联盟》职业比赛到个人游戏理解的深度分析方法

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/3 3:14:48
用Python和数据分析验证乐高泄露套装信息的方法

用Python和数据分析验证乐高泄露套装信息的方法

最近关于乐高 2027/28 年 20 款大套装计划“意外泄露”的话题,在玩家圈子里讨论度很高。各个平台流传的截图、清单、价格表真假混杂,有人兴奋,有人质疑,也有人担心自己提前“被剧透”后失去新鲜感。作为长期关注乐高情报和数据整理…

2026/9/3 3:14:48
音游《CHUNITHM》顶级成就“零號車輛 SSS FC”技术解析与实战指南

音游《CHUNITHM》顶级成就“零號車輛 SSS FC”技术解析与实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/3 3:14:48
C++手写DBF文件解析器:从字节级结构到编码转换实战

C++手写DBF文件解析器:从字节级结构到编码转换实战

简介:面向需要脱离 Visual FoxPro 驱动读写 DBF 文件的 C 开发者,资料包通过自定义 Dbf 类完整演示文件头解析、字段信息读取、记录位图判断及顺序读写流程,适合处理历史数据、跨系统迁移或旧系统集成的中高级程序员。压缩包内共 2 个文件&am…

2026/9/3 3:14:48
STM32+DHT11通过NB-IoT上传OneNET云平台完整指南

STM32+DHT11通过NB-IoT上传OneNET云平台完整指南

简介:一套面向STM32与NB-IoT物联网开发的实战项目资料,以STM32F103C8T6为主控,通过BC260Y模块以MQTT协议将DHT11采集的温湿度数据上报至OneNET云端,适合嵌入式初学者及物联网应用开发者学习参考。资源共151个文件,压缩…

2026/9/3 3:09:48