查看原文
其他

【爬虫+可视化】链家网北京租房信息

爬虫俱乐部 Stata and Python数据分析 2022-03-15

本文作者:寇晓璇,中南财经政法大学统计与数学学院

本文编辑:尚晨曦

技术总编:王子一

Stata&Python云端课程来啦!

好雨知时节,当春乃发生。为了感谢大家长久以来的支持和信任,爬虫俱乐部为大家送福利啦!!!Stata&Python特惠课程双双上线腾讯课堂~原价2400元的Python编程培训课程,现在仅需100元,详情请查看推文《Python云端课程福利大放送!0基础也能学~》。关于Stata,爬虫俱乐部推出了系列课程,内容包括字符串函数、正则表达式、爬虫专题和文本分析,可以随心搭配,价格美丽,物超所值,更多信息可查看Stata系列推文《与春天有个约会,爬虫俱乐部重磅推出正则表达式网络课程!》《与春天有个约会,爬虫俱乐部重磅推出基本字符串函数网络课程》等。变的是价格,不变的是课程质量和答疑服务。对报名有任何疑问欢迎在公众号后台和腾讯课堂留言哦!

目前,租房发展势头迅猛,无论是市场规模还是市场前景,都在向好的方面发展。对于我们而言,无论实习还是工作,都是我们需要关注的内容。今天我们就以北京为例,抓取链家网北京租房信息,并进行简单分析。内容较多,我们直接进入 👇。


内容摘要:

· 爬   虫:  爬取链家网北京租房信息30806条· 可视化:  使用pyecharts对租房信息进行可视化处理


数据抓取


第一步:提取北京各区租房信息

第二步:将得到的数据保存为txt文件

首先,我们进入链家网北京地区页面(https://bj.lianjia.com)。

进入官网后,点击上方租房,进入以下页面。

在此页面上,我们按下CTRL + Shift + I,再点击Network,再按F5,在Name框中会出现一个选项,点击该选项,在右侧点击Headers选项,在最下方找到User-Agent,粘贴到自己的代码即可。如下图所示:
之后,我们按下CTRL + U,打开真实的网页源代码,可以发现里面有我们想要获取的区域、房型、价格、面积等相关信息。

完整代码如下:

1import requests
2from bs4 import BeautifulSoup
3import re
4import time
5
6class LJ:
7    def __init__(self):
8        self.headers = {
9            'User-Agent''Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36'}
10        self.url = 'https://bj.lianjia.com/zufang'
11
12    # 获取某市区域的所有链接
13    def get_areas(self):
14        print('start grabing areas')
15        resposne = requests.get(self.url, headers=self.headers)
16        content = BeautifulSoup(resposne.content, 'lxml')
17        areas = content.find('ul', {'data-target'"area"}).find_all('a')
18        areas.pop(0)
19        for i in areas:
20            area = i.get_text()
21            link = 'https://bj.lianjia.com' + i.get('href')
22            print("开始抓取页面")
23            self.get_pages(area, link)
24
25    # 通过获取某一区域的页数,来拼接某一页的链接
26    def get_pages(self, area, area_link):
27        resposne = requests.get(area_link, headers=self.headers)
28        pages = BeautifulSoup(resposne.content, 'lxml').find('div', {'class':"content__pg"}).get('data-totalpage')
29        print("这个区域有" + pages + "页")
30        for page in range(1, int(pages)+1):
31            url = 'https://bj.lianjia.com/zufang/dongcheng/pg' + str(page)
32            print("开始抓取" + str(page) + "的信息")
33            self.get_house_info(area, url)
34
35    # 获取某一区域某一页的详细房租信息
36    def get_house_info(self, area, url):
37        time.sleep(2)
38        resposne = requests.get(url, headers = self.headers)
39        content = BeautifulSoup(resposne.content, 'lxml')
40        lists = content.find('div', {'class'"content__list"}).find_all('div', {'class'"content__list--item"})
41        for l in lists:
42            title = l.find('a').get('title')
43            square = \
44            re.findall('(\d+)㎡', l.find('div').find('p', {'class'"content__list--item--des"}).get_text())[0]
45
46            floor_info = l.find('div').find('p', {'class'"content__list--item--des"}).find('span').get_text()
47            try:
48                floor = re.findall('([\u4E00-\u9FA5]+)', floor_info)[0]
49                total_floor = re.findall('(\d+)', floor_info)[0]
50            except:
51                floor = ''
52                total_floor = ''
53
54            price = l.find('div').find('span', {'class'"content__list--item-price"}).find('em').get_text()
55
56            with open('链家北京租房.txt''a', encoding='utf-8'as f:
57                f.write(
58                    area + ',' + title + ',' + square + ',' + floor + ',' + total_floor + ',' + price + ',' + '\n')
59
60        print('writing work has done!continue the next page')
61
62def main():
63    print('start!')
64    get = LJ()
65    get.get_areas()
66
67if __name__ == '__main__':
68    main()




数据可视化


将抓取到的数据进行读入,我们可以通过折线图、柱形图、饼图进行展示,从中获取一些规律。

01数据读入

首先,读入第一部分抓取到的数据。

1import pandas as pd
2df = pd.read_table('链家北京租房.txt',header=None, sep=',')
3df.head()
4df = df.drop([6], axis=1)
5df.columns = ['detail_place''title''square''floor''total_floor''price']
6df.head()

显示如下:

02导入相关包
其次,导入pyecharts中需要用到的相关包。
1import pyecharts.options as opts
2from pyecharts.charts import Line
3from pyecharts.charts import Bar
4from pyecharts.charts import Pie
03北京各区房租均价折线图
将爬取到的数据进行处理,制作北京各区房租均价折线图。
1detail_place = df.groupby(['detail_place'])
2house_com = detail_place['price'].agg(['mean','count'])    #agg为聚合函数
3house_com.reset_index(inplace=True)    #set_index(某列)设置某列为索引,reset_index还原回去
4detail_place_main = house_com.sort_values('count',ascending=False)[0:20]    #sort_values()按某一列或几列排序
5
6attr = detail_place_main['detail_place']     
7v1 = detail_place_main['count']
8v2 = detail_place_main['mean']
9
10attr = attr.tolist()
11v1 = v1.tolist()
12v2 = v2.tolist()
13v2 = [round(i,2) for i in v2]    #保留两位小数
14
15#北京各区房租均价折线图
16line = (
17    Line(init_opts=opts.InitOpts(width="1200px", height="600px"))
18    .add_xaxis(xaxis_data=attr)
19    .add_yaxis(
20        series_name="北京各区房租均价",
21        y_axis=v2,
22        markpoint_opts=opts.MarkPointOpts(
23            data=[
24                opts.MarkPointItem(type_="max", name="最大值"),
25                opts.MarkPointItem(type_="min", name="最小值"),
26            ]
27        ),
28    )
29    .set_global_opts(
30        title_opts=opts.TitleOpts(title="北京各区房租均价"),
31        tooltip_opts=opts.TooltipOpts(trigger="axis"),
32        toolbox_opts=opts.ToolboxOpts(is_show=True),
33        xaxis_opts=opts.AxisOpts(type_="category", boundary_gap=False, axislabel_opts={"rotate":45}),
34    )
35
36    .render("北京各区房租均价.html")
37)

可以看出,密云区房租均价最高,为13810.83元/月;大兴区房租均价最低,为9099.88元/月。

04北京各区房屋数量
1#北京各区房屋数量
2bar = (
3    Bar()
4    .add_xaxis(xaxis_data=attr)
5    .add_yaxis("北京各区房屋数量",y_axis=v1, category_gap="80%")
6    .set_global_opts(
7        title_opts=opts.TitleOpts(title="北京各区房屋数量"),
8        xaxis_opts=opts.AxisOpts(axislabel_opts={"rotate":45}),             
9     )
10    .render("北京各区房屋数量.html")
11)

可以看出,在北京所有租房信息中,大兴区房屋数量最多,有1850个;丰台区、海淀区、朝阳区房屋数量也都有1849个;延庆区、平谷区房屋数量最少,都仅有30个。
05房源价格区间分布图
1#房源价格区间分布图
2price_info = df[['detail_place', 'price']]
3#对价格分区
4bins = [0,1000,1500,2000,2500,3000,4000,5000,6000,8000,10000]
5level = ['0-1000','1000-1500', '1500-2000', '2000-3000', '3000-4000', '4000-5000', '5000-6000', '6000-8000', '8000-10000','10000以上']
6price_stage = pd.cut(price_info['price'], bins = bins,labels = level).value_counts().sort_index()
7
8attr = price_stage.index
9v1 = price_stage.values
10attr = attr.tolist()
11v1 = v1.tolist()
12
13bar = (
14    Bar()
15    .add_xaxis(xaxis_data=attr)
16    .add_yaxis("房屋数量", y_axis=v1, category_gap="50%")
17    .set_global_opts(
18        title_opts=opts.TitleOpts(title="价格区间&房源数量分布"),
19        xaxis_opts=opts.AxisOpts(axislabel_opts={"rotate":45}),             
20     )
21    .render("价格区间&房源数量分布.html")
22)

从图中可以看出,房租价格在8000-10000元/月区间内的房源数量最多,为5460个;房租价格在2000元/月以下的房源数量仅有282个。

06房屋面积分布
1#房屋面积分布
2bins =[0,30,60,90,120,150,200,300,400,700]
3level = ['0-30''30-60''60-90''90-120''120-150''150-200''200-300','300-400','400+']
4df['square_level'] = pd.cut(df['square'],bins = bins,labels = level)
5
6df_digit= df[['detail_place''square''total_floor''floor',  'price''square_level']]
7s = df_digit['square_level'].value_counts()
8
9attr = s.index
10v1 = s.values
11attr = attr.tolist()
12v1 = v1.tolist()
13
14pie = (
15    Pie()
16    .add(
17        "",
18        [list(z) for z in zip(attr, v1)],
19        radius=["40%""75%"],
20    )
21    .set_global_opts(
22        title_opts=opts.TitleOpts(title="房屋面积分布"),
23        legend_opts=opts.LegendOpts(orient="vertical", pos_top="15%", pos_left="2%"),
24    )
25    .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}:{d}%"))
26    .render("房屋面积分布.html")
27)

从图中可以看出,房屋面积大都分布在30-90平米,可见小户型居多。而且呈现一种趋势:房屋面积越大所占有的比重越小。

07房屋面积与价位分布
1#房屋面积&价位分布
2bins =[0,30,60,90,120,150,200,300,400,700]
3level = ['0-30''30-60''60-90''90-120''120-150''150-200''200-300','300-400','400+']
4df['square_level'] = pd.cut(df['square'],bins = bins,labels = level)
5
6df_digit= df[['detail_place', 'square', 'total_floor', 'floor',  'price', 'square_level']]
7
8square = df_digit[['square_level','price']]
9prices = square.groupby('square_level').mean().reset_index()
10amount = square.groupby('square_level').count().reset_index()
11
12attr = prices['square_level']
13v1 = prices['price']
14attr = attr.tolist()
15v1 = v1.tolist()
16v1 = [round(i,2for i in v1]
17
18bar = (
19    Bar()
20    .add_xaxis(xaxis_data=attr)
21    .add_yaxis("房屋价位", y_axis=v1, category_gap="50%")
22    .set_global_opts(
23        title_opts=opts.TitleOpts(title="房屋面积&价位分布"),
24        xaxis_opts=opts.AxisOpts(axislabel_opts={"rotate":45}),             
25     )
26    .render("房屋面积&价位分布.html")
27

从图中可以看出,房屋面积越大,房租价格越高。30平方米以下的房屋,房租均价为4318.32元/月;400平方米以上的房屋,房租均价为103366.67元/月。

以上就是全部内容啦,希望对友友们会有所帮助~

最后,我们为大家揭秘雪球网(https://xueqiu.com/)最新所展示的沪深证券和港股关注人数增长Top10。


欢迎大家点赞、评论、转发呦~



对我们的推文累计打赏超过1000元,我们即可给您开具发票,发票类别为“咨询费”。用心做事,不负您的支持!

往期推文推荐

  手把手教你如何获取股票数据和可视化

  Countvalues——数数的超级小帮手

         frame框架进阶篇

 下拉选择框如何变成“小猫咪” | selenium小技巧

  Python中的运算符知多少?

  快来get缺失值的正确打开方式

  frame框架——我到底在哪个“房间”

如何使用Pandas读取txt文件?

基于MySQL数据库实现增量式爬取

寻找春日气息|本月最受欢迎的景点都在这里!

问世间情为何物,大数据也想参悟——后考研时代,何以解忧?唯有数据!

Python与数据库交互—浅述pymysql

偷懒小妙招|selenium之玩转鼠标键盘操作--鼠标篇

大家用Stata来“找茬”

“粉墨登场”——多期双重差分法(DID)的Stata操作

Python与百度地图合璧,绘制棒呆的热力地图

【数据可视化】统计图绘制神器:Seaborn

检索Stata推文的“任意门”学会了这些,分分钟提升你的毕业体验

【爬虫实战】双一流大学的月关注度

【爬虫实战】“中国人不吃这一套”——人民日报微博评论分析

进化的标签管理助手——elabel命令

“学术明星”——双重差分法(DID)的Stata操作

偷懒小妙招| selenium之玩转鼠标键盘操作(上)

【爬虫实战】南京地铁又上热榜——客流量分析

renfiles:批量重命名文件的利器

关于我们 


微信公众号“Stata and Python数据分析”分享实用的Stata、Python等软件的数据处理知识,欢迎转载、打赏。我们是由李春涛教授领导下的研究生及本科生组成的大数据处理和分析团队。



此外,欢迎大家踊跃投稿,介绍一些关于Stata和Python的数据处理和分析技巧。

投稿邮箱:statatraining@163.com投稿要求:
1)必须原创,禁止抄袭;
2)必须准确,详细,有例子,有截图;
注意事项:
1)所有投稿都会经过本公众号运营团队成员的审核,审核通过才可录用,一经录用,会在该推文里为作者署名,并有赏金分成。
2)邮件请注明投稿,邮件名称为“投稿+推文名称”。
3)应广大读者要求,现开通有偿问答服务,如果大家遇到有关数据处理、分析等问题,可以在公众号中提出,只需支付少量赏金,我们会在后期的推文里给予解答。

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存