爬虫练习-爬取房价数据和简单分析

背景介绍

最近房价好像跌了,广大人民(比如我)幻想着换一套好点的房子。于是用爬虫收集一下贝壳网上的二手房数据。懒得新开一个项目了所以放在这个pixiv的爬虫下面。

思路介绍

以上海为例,首先得到了如下链接

  1. https://sh.ke.com/ershoufang

    简单分析下这个页面,我们知道房子信息是按照各个区区分的,如下图所示:
    在这里插入图片描述

  2. 所以我们先获取每个城市的区划信息,这个信息也比较好获得。通过chrome的检查元素,可以很容易看出他"class": "CLICKDATA"

    links_items = bs_html.find_all("a", {"class": "CLICKDATA",
                                              "data-action": "source_type=PC小区列表筛选条件点击"})
            for item in links_items:
                area = {
                    "name_cn": item.text,
                    "url": f"https://sh.ke.com/{item.get('href')}",
                }
    

    每个区,我们只获取他的名字和里面的链接,先存起来

  3. 获得了区的链接和名字,链接大概这样https://sh.ke.com/pudong

    区里面是各个街道,我们下一步是获取街道信息,这里用如下信息来存储

    "towns": [
                        # {
                        #     "name": "北蔡",
                        #     "url": "...",
                        #     "page_num": ""
                        # }
                    ]
    

    通过检查元素,通过如下元素可以获取到

    divs = bs_html.find_all("div", {"data-role": "ershoufang"})
    items = divs[0].find_all("a", {"class": ""})
    
  4. 最后,我们通过如下链接来得到具体房子数据https://sh.ke.com/ershoufang/beicai/pg2/

    可以看到最后有一个页码,我们需要通过页码来拼接链接,从而获取这个街道所有的房子,所以最后一步我们需要来获取每个街道的房子一共有多少页

  5. 通过如下代码获取了页数

    bs_html = ShellSpider.get_bs_html(url)
            pages = bs_html.find_all("div", {
                "class": "page-box house-lst-page-box",
                "comp-module": "page"
            })
            page_dict = json.loads(pages[0].get("page-data"))
            town["page_num"] = page_dict["totalPage"]
    
  6. 有了页码,我们可以拼接出链接了,接下来就是通过request不断请求每一页,来获取房子数据了,我们小区名,房屋信息,总价,单价。

    for info_div in info_divs:
                # 分别获取小区名,房屋信息,总价,单价
                community_name = fmt_info(info_div.find('div', class_='positionInfo').text)
                house_info = fmt_info(info_div.find('div', class_='houseInfo').text)
                total_price = fmt_info(info_div.find('div', class_='totalPrice totalPrice2').text)
                total_price = fmt_price(total_price)
                unit_price = fmt_info(info_div.find('div', class_='unitPrice').text)
                unit_price = fmt_price(unit_price)
    
  7. 最终,我们用一个Pandas的DataFrame对象来存储所有房子信息,然后再存储在Excel文件或者Mysql数据库中

代码介绍

不如直接看注释,注释我尽可能写的详细了

https://github.com/h-kayotin/hanayo_pixiv

如何运行

克隆代码,并安装所有依赖库(见requirements.txt)后,直接运行*kayotin_house.py*

程序运行约需要15分钟,大约有9万条数据(2023年7月),请耐心等待。

其他参数

默认爬取上海的数据,如需其他城市,请先按如下添加其他城市代码

city_names = {
        "sh": "上海",
        "gz": "广州"
    }

然后在main中做如下修改:

my_spider = ShellSpider("shell", city="gz")

默认保存在Excel文件,需要要mysql,请设置mysql为true

数据库结构如下:

CREATE table tb_sh
(
house_id int auto_increment COMMENT "编号",
area VARCHAR(255) not null comment "区",
street VARCHAR(255) not null comment "街道",
community VARCHAR(255) comment "小区",
info VARCHAR(1024) comment "房子信息",
total FLOAT comment "总价(万元)",
unit FLOAT comment "单价(元)",
date DATE comment "日期",
PRIMARY key (house_id)
)

运行如下代码保存到数据库:

# 以下代码用于读取excel数据,存储到mysql
    # my_spider.house_info_df = pd.read_excel(io="datas/house/上海2023-07-17/房价数据.xlsx", index_col="id")
    # my_spider.save_to_mysql()

数据分析

导入数据

house_data = pd.read_excel(io="房价数据.xlsx", index_col="id")

以下total单位是万元,unit单位是元
数据总览

整体数据

贵的

  1. 首先来看一下,上海整体的均价和单价

    print("房子总价的平均值是:", f"{house_data['total'].mean():.2f}万元")
    print("单价的平均值是:", f"{house_data['unit'].mean():.2f}元")
    

    可以得到:

    均价是: 633.15万元
    单价平均值是: 66233.43元

  2. 然后我们来看一下最贵的top10,可以看到下图中,基本都是面积很大的房子,有钱人的快乐确实想象不到,如果住在2千平米的房子里,怕是真的每天要从两百米的床上醒来了。

    house_data.nlargest(10, "total")
    

    在这里插入图片描述

  3. 再来看一下,单价最贵的top10。其中一平就34万的房子,是真的厉害。

    house_data.nlargest(10, "unit")
    

在这里插入图片描述

便宜的

  1. 看一下最便宜的top10
    house_data.nsmallest(10, "total")
    
    在这里插入图片描述
  2. 单价最便宜的top10
    house_data.nsmallest(10, "unit")
    
    在这里插入图片描述
    看来在上海不努力,就要去金山做邻居了。

各区价格排序

统计每个区房子的均价,然后按照从高到低排序,可以看到黄浦区才是人上人。

area_df_total = round(house_data.groupby("area").total.mean(), 2)
df1 = pd.DataFrame(area_df_total.sort_values(ascending=False))
df1 = df1.T
df1

在这里插入图片描述

以下是单价排序

area_df_total = round(house_data.groupby("area").unit.mean()/ 10000, 2)
area_df_total = area_df_total.sort_values(ascending=False)
df2 = pd.DataFrame(area_df_total).T
df2

在这里插入图片描述

各街道价格排序

我们来看看哪个街道最贵吧,毕竟以区来说,范围还是大了一点

street_prices_high = house_data.groupby("street").agg({
    "total": ["mean"], "area": ["first"]
}).reset_index()
street_prices_high.columns = ["街道", "总价", "区"]
street_prices_high = street_prices_high.nlargest(10, "总价").reset_index()
street_prices_high = round(street_prices_high, 2)
street_prices_high

在这里插入图片描述
竟然不是黄浦,那么看看单价呢

street_unit_df = house_data.groupby("street").agg({
    "unit": ["mean"], "area": ["first"]
}).reset_index()
street_unit_df.columns = ["街道", "平均单价", "区"]
street_unit_df = street_unit_df.nlargest(10, "平均单价")
street_unit_df = round(street_unit_df, 2)
street_unit_df

在这里插入图片描述
看单价的数据就合理多了,确实是黄浦的街道最贵。

各小区价格排序

我们直接来看单价吧

comm_unit_df = house_data.groupby("community").agg({
    "unit": ["mean"], "street": ["first"], "area": ["first"]
}).reset_index()
comm_unit_df.columns = ["小区", "平均单价", "街道", "区"]
comm_top10 = comm_unit_df.nlargest(10, "平均单价")
comm_top10.平均单价 = round(comm_top10.平均单价 / 10000, 2)
comm_top10

在这里插入图片描述
确实很合理,虽然黄浦还是最多的,但是浦东也有上榜,符合广大人民的刻板印象。

普陀区情况分析

为什么调了普陀区来分析呢,首先我住在普陀。其次普陀的房子勉强还在努力一下买的起的范围内,但是普通真的是市区发展最差的一个,建议能在其他区就别来普陀。

筛选出普陀的数据
putuo_df = house_data.query("area == '普陀'")
putuo_df
直接找普陀单价最贵的小区吧:
putuo_commu_df = putuo_df.groupby("community").agg({
    "unit": ["mean"], "street": ["first"], "area": ["first"]
}).reset_index()
putuo_commu_df.columns = ["小区", "平均单价", "街道", "区"]
putuo_commu_df["平均单价"] = round(putuo_commu_df["平均单价"] / 10000, 2)
pt_commu_top10 = putuo_commu_df.nlargest(10, "平均单价")
pt_commu_top10

在这里插入图片描述
最便宜的:
在这里插入图片描述

普陀各街道情况

看下各街道房价排名情况吧

pt_street_df = putuo_df.groupby("street").agg({
    "unit": ["mean"]}).reset_index()
pt_street_df.columns = ["街道", "平均单价"]
pt_street_df.sort_values("平均单价", ascending=False, inplace=True)
pt_street_df["平均单价"] = round(pt_street_df["平均单价"] / 10000, 2)
pt_street_df = pt_street_df.T
pt_street_df

在这里插入图片描述
OK,到这里已经看到我熟悉的小区了和街道了,大概了解了情况。虽然没什么卵用,但是学习了一下用pandas做数据分析。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值