【愚公系列】《Python网络爬虫从入门到精通》043-案例:可视化二手房数据查询系统
【摘要】 标题详情作者简介愚公搬代码头衔华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,CSDN商业化专家,阿里云专家博主,阿里云签约作者,腾讯云优秀博主,腾讯云内容共创官,掘金优秀博主,亚马逊技领云博主,51CTO博客专家等。近期荣誉2022年度博客之星TOP2,2023年度博客之星TOP2,2022年华为云十佳博主,2023年华为云十佳博主,2024年华为云十佳...
标题 | 详情 |
---|---|
作者简介 | 愚公搬代码 |
头衔 | 华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,CSDN商业化专家,阿里云专家博主,阿里云签约作者,腾讯云优秀博主,腾讯云内容共创官,掘金优秀博主,亚马逊技领云博主,51CTO博客专家等。 |
近期荣誉 | 2022年度博客之星TOP2,2023年度博客之星TOP2,2022年华为云十佳博主,2023年华为云十佳博主,2024年华为云十佳博主等。 |
博客内容 | .NET、Java、Python、Go、Node、前端、IOS、Android、鸿蒙、Linux、物联网、网络安全、大数据、人工智能、U3D游戏、小程序等相关领域知识。 |
欢迎 | 👍点赞、✍评论、⭐收藏 |
🚀前言
在当今数据驱动的时代,网络爬虫技术为我们提供了获取和分析信息的强大工具。尤其在房地产领域,随着二手房市场的蓬勃发展,如何快速、高效地获取房源信息,并将其可视化,以辅助决策和研究,成为了许多数据分析师和开发者关注的热点问题。
在本篇文章中,我们将通过一个实际案例,展示如何利用Python的网络爬虫技术抓取二手房的数据,并将这些数据进行可视化处理。我们将从数据获取的基本步骤开始,逐步深入到数据清洗、存储以及最终的可视化展示,帮助你全面理解整个数据处理流程。
通过具体的实例,你不仅可以学到如何使用流行的爬虫库(如Scrapy或BeautifulSoup)来抓取数据,还将掌握如何使用可视化工具(如Matplotlib或Seaborn)将数据转换为易于理解的图表。这一过程将为你提供实用的技能,帮助你在实际项目中游刃有余。
🚀一、案例:可视化二手房数据查询系统
🔎1.数据爬取与分析
🦋(1) 网页地址规律分析
-
URL 结构: https://cc.lianjia.com/ershoufang/pg{页码}/
-
页码从 1
到100
(示例爬取前100页)。 -
示例:第一页为 pg1
,第二页为pg2
。
-

🦋(2) 数据字段提取
-
目标字段: -
小区名称、总价(万元)、户型、建筑面积(㎡)、单价(元/㎡)、区域。
-
-
HTML 解析规则(基于开发者工具定位): # 示例XPath定位(具体根据实际网页结构调整) 小区名称: '//div[1]/div[2]/div/a[1]/text()' 总价: '//div[1]/div[6]/div[1]/span/text()' + '万' 区域: '//div[1]/div[2]/div/a[2]/text()' 单价: '//div[1]/div[6]/div[2]/span/text()' 户型与面积: '//div[1]/div[3]/div/text()'(需字符串分割处理)
🔎2.系统核心代码实现
🦋(1) 模块导入与全局配置
from requests_html import HTMLSession # 导入HTMLSession类
from requests_html import UserAgent # 导入UserAgent类
from requests_html import HTML # 导入HTML类
import pandas as pd# 导入pandas模块
import matplotlib # 导入图表模块
import matplotlib.pyplot as plt # 导入绘图模块
# 避免中文乱码
matplotlib.rcParams['font.sans-serif'] = ['SimHei']
matplotlib.rcParams['axes.unicode_minus'] = False
from multiprocessing import Pool # 导入进程池
# 分类列表,作为数据表中的列名
class_name_list = ['小区名字', '总价', '户型', '建筑面积', '单价', '区域']
# 创建DataFrame临时表格
df = pd.DataFrame(columns=class_name_list)
🦋(2) 控制台菜单与主程序
def menu():
# 输出菜单
print('''
╔——————可视化二手房数据查询系统—————╗
│ │
│ =============== 功能菜单 ===============│
│ │
│ 1 爬取最新二手房数据 │
│ 2 查看各区二手房数量比例 │
│ 3 查看各区二手房均价 │
│ 4 查看热门户型均价 │
│ 0 退出系统 │
│==========================================│
╚———————————————————————╝
''')
def main():
ctrl = True # 标记是否退出系统
while (ctrl):
menu() # 显示菜单
option = input("请选择:") # 选择菜单项
if option in ['0', '1', '2', '3', '4']:
option_int = int(option)
if option_int == 0: # 退出系统
print('退出可视化二手房数据查询系统!')
ctrl = False
elif option_int == 1: # 爬取最新二手房数据
print('爬取最新二手房数据')
start_crawler() # 启动多进程爬虫
print('二手房数据爬取完毕!')
elif option_int == 2: # 查看各区房子数量比例
show_house_number()
print('查看各区房子数量比例')
elif option_int == 3: # 查看各区二手房均价
show_average_price()
print('查看各区二手房均价')
elif option_int == 4: # 查看热门户型均价
show_type()
print('查看热门户型均价')
else:
print('请输入正确的功能选项!')
🦋 (3) 多进程爬虫实现
def start_crawler():
df.to_csv("二手房数据.csv", encoding='utf_8_sig') # 第一次生成带表头的空文件
url = 'https://cc.lianjia.com/ershoufang/pg{}/'
urls = [url.format(str(i)) for i in range(1, 101)]
pool = Pool(processes=4) # 创建4进程对象
pool.map(get_house_info, urls)
pool.close() # 关闭进程池
def get_house_info(url):
session = HTMLSession() # 创建HTML会话对象
ua = UserAgent().random # 创建随机请求头
response = session.get(url, headers={'user-agent': ua}) # 发送网络请求
if response.status_code == 200: # 判断请求是否成功
html = HTML(html=response.text) # 解析HTML
li_all = html.find('.sellListContent li') # 获取每页所有房子信息
for li in li_all:
name = li.xpath('//div[1]/div[2]/div/a[1]/text()')[0].strip()# 获取小区名称
# 获取房子总价
total_price = li.xpath('//div[1]/div[6]/div[1]/span/text()')[0] + '万'
region = li.xpath('//div[1]/div[2]/div/a[2]/text()')[0] # 获取房子区域
unit_price = li.xpath('//div[1]/div[6]/div[2]/span/text()')[0]# 获取房子单价
house_info = li.xpath('//div[1]/div[3]/div/text()')[0] # 获取房子详细信息
house_list = house_info.split('|') # 使用|分割房子详细信息
type = house_list[0].strip() # 获取房子户型
dimensions = house_list[1].strip() # 获取房子面积
# '小区名字', '总价', '户型', '建筑面积', '单价', '区域'
print(name,total_price,type,dimensions,unit_price,region)
# 将数据信息添加至DataFrame临时表格中
df.loc[len(df) + 1] = {'小区名字': name, '总价': total_price, '户型': type,
'建筑面积': dimensions, '单价': unit_price, '区域': region}
# 将数据以添加模式写入csv文件当中,不再添加头部列
df.to_csv("二手房数据.csv", mode='a', header=False)
else:
print(response.status_code)
🔎3.数据可视化功能实现
🦋(1) 各区房源数量比例(饼图)
def cleaning_data():
data = pd.read_csv('二手房数据.csv') # 读取csv数据文件
del data['Unnamed: 0'] # 将索引列删除
data.dropna(axis=0, how='any', inplace=True) # 删除data数据中的所有空值
data = data.drop_duplicates() # 删除重复数据
# 将单价“元/平米”去掉
data['单价'] = data['单价'].map(lambda d: d.replace('元/平米', ''))
data['单价'] = data['单价'].map(lambda d: d.replace('单价', ''))# 将单价“元/平米”去掉
data['单价'] = data['单价'].astype(float) # 将房子单价转换为浮点类型
return data
# 显示各区二手房数量所占比例
def show_house_number():
data = cleaning_data() # 获取清洗后的数据
group_number = data.groupby('区域').size() # 房子区域分组数量
region = group_number.index # 区域
numbers = group_number.values # 获取每个区域内房子出售的数量
percentage = numbers / numbers.sum() * 100 # 计算每个区域房子数量的百分比
plt.figure() # 图形画布
plt.pie(percentage, labels=region,labeldistance=1.05,
autopct="%1.1f%%", shadow=True, startangle=0, pctdistance=0.6)
plt.axis("equal") # 设置横轴和纵轴大小相等,这样饼才是圆的
plt.title('各区二手房数量所占比例', fontsize=12)
plt.show() # 显示饼图
🦋(2) 各区二手房均价(柱形图)
def show_average_price():
data = cleaning_data() # 获取清洗后的数据
group = data.groupby('区域') # 将房子区域分组
average_price_group = group['单价'].mean() # 计算每个区域的均价
region = average_price_group.index # 区域
average_price = average_price_group.values.astype(int) # 区域对应的均价
plt.figure() # 图形画布
plt.bar(region,average_price, alpha=0.8) # 绘制柱形图
plt.xlabel("区域") # 区域文字
plt.ylabel("均价") # 均价文字
plt.title('各区二手房均价') # 表标题文字
# 为每一个图形加数值标签
for x, y in enumerate(average_price):
plt.text(x, y + 100, y, ha='center')
plt.show() # 显示图表
🦋 (3) 热门户型均价分析
def show_type():
data = cleaning_data() # 获取清洗后的数据
house_type_number = data.groupby('户型').size() # 房子户型分组数量
sort_values = house_type_number.sort_values(ascending=False)# 将户型分组数量进行降序
top_five = sort_values.head(5) # 提取前5组户型数据
house_type_mean = data.groupby('户型')['单价'].mean() # 计算每个户型的均价
type = house_type_mean[top_five.index].index # 户型
price = house_type_mean[top_five.index].values # 户型对应的均价
price = price.astype(int)
plt.figure() # 图形画布
plt.barh(type, price, height=0.3, color='r', alpha=0.8) # 从下往上画水平柱形图
plt.xlim(0, 15000) # X轴的均价0~15000
plt.xlabel("均价") # 均价文字
plt.title("热门户型均价") # 表标题文字
# 为每一个图形加数值标签
for y, x in enumerate(price):
plt.text(x + 10, y, str(x) + '元', va='center')
plt.show() # 显示图表
if __name__ == '__main__': # 创建程序入口
main() # 调用自定义main()方法
🔎4.运行效果示例
-
系统菜单:
-
爬取数据控制台输出:
🔎5.注意事项
-
依赖安装: pip install requests-html pandas matplotlib
-
反爬限制: -
链家网可能对高频请求进行封禁,需合理设置爬取速度或使用代理IP。
-
-
数据更新: -
爬取前检查URL结构是否变更,及时调整XPath定位规则。
-
-
文件路径: -
确保程序有权限读写当前目录下的 二手房数据.csv
。
-
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)