python语言,在数据分析方面,涵盖了“数据获取→数据处理→数据分析→数据可视化”这个流程中每个环节,不可不谓之为利器。

本篇文章我们就利用python语言在数据分析方面的应用,来实现从数据的抓取,清洗到分析和数据可视化,这个完整的闭环:

通过使用requests库对链家网二手房列表页进行抓取。

通过BeautifulSoup对页面进行解析,并从中获取房源价格,面积,户型和关注度的数据。

最后再利用python的pandas,matplotlib模块对数据进行处理和分析。

0,环境搭建

环境:win10+Anaconda +jupyter Notebook

模块:

爬虫和网页解析相关的模块:requests,BeautifulSoup,time

数据分析模块:Numpy,pandas,

画图模块:matplotlib,

1,构建爬虫,抓取需要的信息

A,导入爬虫相关的模块

import requests,time

from bs4 import BeautifulSoup

requests,负责网络请求。

BeautifulSoup,负责网页解析。

Time,负责设置每次抓取的休息时间。

B,分析网页

开始抓取前先观察下目标页面或网站的结构,其中比较重要的是URL的结构。

链家网的二手房列表页面共有100个,URL结构为http://bj.lianjia.com/ershoufang/pg2/,其中bj表示城市,/ershoufang/是频道名称,pg3是页面码。我们要抓取的是北京的二手房频道,所以前面的部分不会变,属于固定部分,后面的页面码需要在1-100间变化,属于可变部分。我们可以用for循环构造要请求的url。

#这里,我们抓取100个页面的数据

for i in range(1, 100):

url='http://bj.lianjia.com/ershoufang/pg'+str(i)+"/"

#我们可以先看下网址是否构造正确

for i in range(1, 10):

url='http://bj.lianjia.com/ershoufang/pg'+str(i)+"/"

print(url)

#输出:

https://bj.lianjia.com/ershoufang/pg1/

https://bj.lianjia.com/ershoufang/pg2/

https://bj.lianjia.com/ershoufang/pg3/

https://bj.lianjia.com/ershoufang/pg4/

https://bj.lianjia.com/ershoufang/pg5/

https://bj.lianjia.com/ershoufang/pg6/

https://bj.lianjia.com/ershoufang/pg7/

https://bj.lianjia.com/ershoufang/pg8/

https://bj.lianjia.com/ershoufang/pg9/

C,构造爬虫

headers={

'Accept':'application/json, text/javascript, */*; q=0.01',

'Accept-Encoding':'gzip, deflate, br',

'Accept-Language':'zh-CN,zh;q=0.8',

'Connection':'keep-alive',

'Referer':'http://www.baidu.com/link?url=_andhfsjjjKRgEWkj7i9cFmYYGsisrnm2A-TN3XZDQXxvGsM9k9ZZSnikW2Yds4s&wd=&eqid=c3435a7d00006bd600000003582bfd1f'

}

for i in range(1, 100):

url='http://bj.lianjia.com/ershoufang/pg'+str(i)+"/"

res = requests.get(url=url,headers=headers)

html = res.text

time.sleep(0.7)

在这里需要特别注意一下:为了尽量伪装成正常的请求,我们需要在http请求中设置一个头部信息,否则很容易被封。头部信息网上有很多现成的。

手动设置每次请求的时间间隔。

D,输出到屏幕上,看看爬取是否成功

ok,没问题,我们接下来,对这些页面进行解析,提取需要的信息。

E,解析页面,提取信息

lj=BeautifulSoup(html,'html.parser')

#提取价格信息

price = lj.find_all("div",attrs={"class":"priceInfo"})

tpc = []

for p in price:

totalPrice = p.span.string

tpc.append(totalPrice)

#提取房源信息

houseInfo = lj.find_all("div",attrs={"class":"houseInfo"})

hio=[]

for h in houseInfo:

house = h.get_text()

hio.append(house)

#提取关注度信息

followInfo = lj.find_all("div",attrs={"class":"followInfo"})

fio = []

for f in followInfo:

follow = f.get_text()

fio.append(follow)

##创建数据表(构造DataFrame)

import pandas as pd

house = pd.DataFrame({"totalprice":tpc,"houseinfo":hio,"followinfo":fio})

#检查下数据集构造的情况

house.head()

虽然我们已经把提取的信息构造为DataFarme结构的数据,但明显能看到,这个数据集有些粗糙。如房源信息,在数据集中每个房源的小区名称,户型,面积,朝向等信息都在一个字段中,无法直接使用。所以我们还需要,对数据集进行进一步的处理。

2,数据处理(特征构造)

数据处理的内容主要是对数据集进行数据清洗和加工。

数据清洗:

当我们利用爬虫从网络中爬取数据,数据集中容易出现垃圾数据(空格,乱码,特殊符号等),空值,异常值(字母大小写未区分,不匹配的数据类型等)问题,对数据集做处理时候,首先要特别注意这些问题(这属于数据处理中的准备工作,这里里就不展示了,有兴趣的朋友可以看看专栏中之前的几篇文章,都有说明)。

数据加工:

数据清洗完毕后,我们根据分析所需要的数据信息,再对数据集的字段,进行一些新的特征的构造。

数据处理的的目的是为了让数据集变得更利于下一步分析。

从houseinfo字段中,新构造出“小区”,“户型”,“面积”等特征

从followinfo字段中,新构造出“关注度”特征

其实这里的操作,就相当于Excel中的分列操作,在分列操作中,尽量把原有字段切分成

每一个新字段都是最小颗粒度(不可再分)特征的字段。

house["xiaoqu"] = house["houseinfo"].apply(lambda x: x.split("|")[0].strip())

house["huxing"] = house["houseinfo"].apply(lambda x: x.split("|")[1].strip())

house["mianji"] = house["houseinfo"].apply(lambda x: x.split("|")[2].strip())

house["guanzhu"] = house["followinfo"].apply(lambda x: x.split("|")[0].strip())从面积字段中提取面积的数字,注意这里要转化为float格式,以便于后续的计算

#定义函数,利用正则表达式,取得mianji字段中,字符串中的数字

import re

def get_num(string):

return (re.findall("\d+\.?\d*",string)[0])

#使用apply()方法,对mianji使用函数get_num

house["mianji_num"] = house.mianji.apply(get_num)

house.head()

#更改mianji_num字段格式为float

house['mianji_num']=house['mianji_num'].astype(float)

从关注字段中提取关注的数字,注意这里要转化为float格式,以便于后续的计算

#定义函数,利用正则表达式,取得followinfo字段中,字符串中的数字

import re

def get_num(string):

return (re.findall("\d+\.?\d*",string)[0])

#使用apply()方法,对guanzhu字段使用函数get_num

house["guanzhu_num"] = house.guanzhu.apply(get_num)

house.head()

#更改房源关注度及总价字段的格式

house[['guanzhu_num','totalprice']]=house[['guanzhu_num','totalprice']].astype(float)

3,数据分析(数据探索和可视化)

探索性数据分析(Exploratory Data Analysis,简称EDA)目的是最大化对数据的直觉,完成这个事情的方法只能是结合统计学的图形以各种形式展现出来。通常涉及以下几种方法的组合:原始数据集中每个字段的单变量可视化和汇总统计

数据集中每个自变量与目标变量之间的关系的双变量可视化和汇总统计

多元可视化以了解数据中不同字段之间的交互作用

让观察值聚类成有区别的小组

我们这里对处理后的数据简单的进行几个特征的探索性分析。

A,房源户型分布情况

前面我们经过对房源信息的分列获取了房源的朝向,户型等信息,这里我们对房源的户型情况进行汇总,看看北京在售二手房的户型分布情况。

首先按房源的户型对房源数量进行汇总:

huxing = house.groupby(["huxing"])["huxing"].agg("count")

huxing

#输出:

huxing

1室0厅 53

1室1厅 257

1室2厅 15

2室0厅 5

2室1厅 1425

2室2厅 270

2室3厅 1

3室0厅 4

3室1厅 495

3室2厅 297

3室3厅 8

4室1厅 20

4室2厅 83

4室3厅 11

5室2厅 15

5室3厅 1

6室1厅 1

6室2厅 3

6室4厅 1

Name: huxing, dtype: int64

绘制条形图,从户型的角度看下房源的分布:

#绘制房源户型分布条形图

'''

plt.rcParams['figure.figsize'] = (12, 8)#用来设置图像显示大小

plt.rcParams['font.sans-serif'] = ['STXihei'] #用来正常显示中文标签

plt.rcParams['axes.unicode_minus'] = False #用来正常显示负号

'''

plt.rc('figure', figsize=(12, 8))#plt.figure(figsize = (12,8))

plt.rc('font', family='STXihei', size=15)

a=np.array([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20])

plt.barh([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20],huxing,color='#99CC01',alpha=0.8,align='center',edgecolor='white')

plt.ylabel('户型')

plt.xlabel('数量')

plt.xlim(0,1500)

plt.ylim(0,20)

plt.title('房源户型分布情况')

plt.legend(['数量'], loc='upper right')

plt.grid(color='#95a5a6',linestyle='--', linewidth=1,axis='y',alpha=0.4)

plt.yticks(a,('1室0厅','1室1厅','1室2厅','2室0厅','2室1厅','2室2厅','2室2厅','3室0厅','3室1厅','3室2厅','3室3厅','4室1厅','4室2厅','4室3厅','5室2厅','5室3厅','6室1厅','6室2厅','6室3厅','6室4厅'))

plt.show()

北京在售二手房中户型从1室0厅到6室4厅近19种分布广泛。在所有的户型中数量最多的是2室1厅,其次为3室1厅和3室2厅,以及2室2厅。较小的1室1厅数量也较多。

B,房源面积分布情况

首先查看所有北京在售二手房的面积范围

#查看所有房源面积的范围值

house['mianji_num'].min(),house['mianji_num'].max()

#输出:

(25.550000000000001, 367.19)

绘制条形图,从面积的角度看下房源的分布:

#对房源面积进行分组

bins = [0, 50, 100, 150, 200, 250, 300, 350]

group_mianji = ['小于50', '50-100', '100-150', '150-200','200-250','250-300','300-350']

house['group_mianji'] = pd.cut(house['mianji_num'], bins, labels=group_mianji)

#按房源面积分组对房源数量进行汇总

group_mianji=house.groupby('group_mianji')['group_mianji'].agg(len)

绘制房源面积分布图

plt.figure(figsize = (12,8))

plt.rc('font', size=15)

a=np.array([1,2,3,4,5,6,7])

plt.barh([1,2,3,4,5,6,7],group_mianji,color='#99CC01',alpha=0.8,align='center',edgecolor='white')

plt.ylabel('面积分组')

plt.xlabel('数量')

plt.title('房源面积分布')

plt.legend(['数量'], loc='upper right')

plt.grid(color='#95a5a6',linestyle='--', linewidth=1,axis='y',alpha=0.4)

plt.yticks(a,('小于50', '50-100', '100-150', '150-200','200-250','250-300','300-350'))

plt.show()

在所有房源中,数量最多的是50-100,其次为100-150。随着面积增加数量减少。小于50的小面积房源也有一定数量的房源。

C,房源关注度的分布情况

首先查看所有北京在售二手房的关注度区间

#查看房源关注度的区间

house['guanzhu_num'].min(),house['guanzhu_num'].max()

#输出:

(0.0, 965.0)

关注度从0到965。也就是说有些房子很热门,而有些房子没有人关注。

这可能和房源上线和更新的情况有关,此外还要考虑房源的销售速度,热门房源可能很抢手,刚上线就成交了。因此我们对情况进行简化,暂时忽略掉这些复杂的情况。仅对关注度的分布情况进行统计。

#对房源关注度进行分组

bins = [0, 100, 200, 300, 400, 500, 600, 700,800]

group_guanzhu = ['小于100', '100-200', '200-300', '300-400','400-500','500-600','600-700','700-800']

house['group_guanzhu'] = pd.cut(house['guanzhu_num'], bins, labels=group_guanzhu)

group_guanzhu=house.groupby('group_guanzhu')['group_guanzhu'].agg(len)

#绘制房源关注度分布图

plt.figure(figsize = (12,8))

plt.rc('font', size=15)

a=np.array([1,2,3,4,5,6,7,8])

plt.barh([1,2,3,4,5,6,7,8],group_guanzhu,color='#99CC01',alpha=0.8,align='center',edgecolor='white')

plt.ylabel('关注度分组')

plt.xlabel('数量')

plt.xlim(0,3000)

plt.title('房源关注度分布')

plt.legend(['数量'], loc='upper right')

plt.grid(color='#95a5a6',linestyle='--', linewidth=1,axis='y',alpha=0.4)

plt.yticks(a,('小于100', '100-200', '200-300', '300-400','400-500','500-600','600-700','700-800'))

plt.show()

在3000个房源中,近2500个房源的关注度小于100,关注度大于400的房源则较少。这里需要再次说明的是关注度数据无法准确的表示房源的热门程度。在实际业务中,热门房源可能由于出售速度快而关注度较少。

D,房源聚类分析

我们对所有在售房源按总价,面积和关注度进行聚类分析。将在售房源按总价,面积和关注度的相似性分在不同的类别中。

#导入sklearn中的KMeans进行聚类分析

from sklearn.cluster import KMeans

#使用房源总价,面积和关注度三个字段进行聚类

house_type = np.array(house[['totalprice','mianji_num','guanzhu_num']])

#设置n_clusters=3

clf=KMeans(n_clusters=3)

#计算聚类结果

clf=clf.fit(house_type)

#查看分类结果的中心坐标

clf.cluster_centers_

#输出:

array([[ 922.79075862, 119.53848276, 72.85241379],

[ 444.58505639, 81.17239192, 86.92575188],

[ 1866.09821429, 194.84982143, 78.375 ]])

#在原数据表中标注房子所属类别

house['label']= clf.labels_

根据三个类别在总价,面积和关注度三个点的中心坐标,我们将在售房源分为三个类别:

总价:低 面积 :低 关注度:高

总价:中 面积 :中 关注度:中

总价:高 面积 :高 关注度:低

第一个类别是总价低,面积低,关注度高的房源。

第二个类别是总价居中,面积居中,关注度居中的类别。

第三个类别是总价高,面积高,关注度低的类别。

从上述分析看出,按照实际业务出发,在广告和列表页的默认排序中应该给予总价400万左右,面积80平米左右的房源更高的权重。这个类别的房源可以吸引最多的用户关注。

结束语

数据分析的基本流程包括:数据获取→数据处理→数据分析→结果呈现。本篇文章我们利用python语言在数据分析方面的应用,实现了从数据的抓取,清洗到分析和数据可视化,整个完整的闭环。在实际操作中,往往并不像展示的这么简单,展示在文章中的只是分析流程,分析代码,以及分析结果。但这的背后的大量操作,往往十分琐碎苦逼。

但古人有句话说得好“亦余心之所善兮, 虽九死其犹未悔!”,借此话,以共勉!

python爬虫requests源码链家_python数据分析实例:python抓取链家二手房源数据和分析...相关推荐

  1. python爬虫requests源码链家_python的爬虫项目(链家买二手房)

    不知不觉,已经工作6年有余,恍恍惚惚,有机会满足房子需求. 在收集房子信息过程中,做些记录. 贝壳的功能很强大,但很难满足小区.距离.教育.面积等多个方面的匹配,使用起来成本仍然较高. 针对以上情况, ...

  2. python爬虫requests源码链家_python爬虫——爬取链家房价信息(未完待续)

    爬取链家房价信息(未完待续) items.py # -*- coding: utf-8 -*- # Define here the models for your scraped items # # ...

  3. python爬虫requests源码链家_python爬虫爬取链家二手房信息

    #coding=utf-8 import requests from fake_useragent import UserAgent from bs4 import BeautifulSoup imp ...

  4. python爬虫requests源码链家_链家房源爬虫(含源码)

    链家APP上有很多在售房源信息以及成交房源信息,如果可以把这些信息爬下来,可以得到很多有价值的信息.因此本文将讲一讲如何爬取这些数据,并保存下来供以后分析. 本文将介绍以下几个方面: 程序介绍该程序支 ...

  5. python爬虫搜特定内容的论文_python基于BeautifulSoup实现抓取网页指定内容的方法...

    python基于BeautifulSoup实现抓取网页指定内容的方法 更新时间:2015年07月09日 10:12:50 作者:光索与诺 这篇文章主要介绍了python基于BeautifulSoup实 ...

  6. python爬虫requests源码链家_Python 爬虫 链家二手房(自行输入城市爬取)

    因同事想在沈阳买房,对比分析沈阳各区的房价,让我帮忙爬取一下链家网相关数据,然后打 算记下笔记 用于总结学到的东西&用到的东西. 一.爬虫需要会什么? 学习东西 首先你要知道它是干嘛的.爬虫 ...

  7. python爬虫requests源码链家_Python爬虫系列-Xpath自如和bs4链家

    爬完魔方之后,再接再厉爬取自如和链家,然后...不出意外的又失败了!在向右老师和羽恒大神的拯救下,终于把我从坑里挖了出来.虽然错的也还有点稀里糊涂的,但前事不忘,后事之师.下面把遇到的坑简单说一下. ...

  8. python爬虫requests源码链家_Python爬虫之---爬链家

    一个简单的实例,可以采用.做的demo. #!/usr/bin/python # -*- coding: utf-8 -*- # @Time : 2020/6/4 15:55 # @Author : ...

  9. python爬虫120源码DIY--001--抓取桌面壁纸

    python爬虫120源码DIY–001–抓取桌面壁纸 ​ 本次抓取所用目标网址:http://www.netbian.com/fengjing/,内含N多高清壁纸图,初始只是预览图,真正的高清图在后 ...

最新文章

  1. 谷歌开放的TensorFlow Object Detection API 效果如何?对业界有什么影响
  2. tightvnc viewer 传文件_TightVNC中文版下载_TightVNC viewer(远程控制软件)简体中文版下载【32位|64位】-华军软件园...
  3. mybatis-generator-gu(mybatis generator 的图形界面工具)
  4. 模拟四:STEMA 考试选择题模拟练习试卷(中级组)及答案 + 自我解题笔记
  5. php获得注册信息,PHP网络编程:获取用户的注册信息[2]
  6. 一对一,一对多,多对多查询 (注解写法)
  7. html5怎么删除样式,css怎么删除一个样式
  8. 使用J2SE API读取Properties文件的六种方法(选择自 kindani 的 Blog )
  9. 云网络的守护神:主动链路监控
  10. html拖拽吸附插件,前端拖拽插件gridster.js
  11. Android 自定义View关于measure流程的基本思路整理
  12. 仪表指针样式_PPT标准图表太丑?试试仪表盘图表!
  13. 中国行政区划代码,包括五级行政区划详细代码,县级以上区划地理围栏
  14. 史上最好用的Mysql历史数据归档工具
  15. 《程序员》2012年7期精彩内容:智能算法
  16. iText7-pdfoffice-office文件转pdf
  17. 记录一次自己搭建服务器的历程(机架式服务器,Linux系统)
  18. diskpart clean 误操作恢复
  19. 计算机网络学习笔记 3.6 局域网
  20. Python match-search-findall-group(s)的区别

热门文章

  1. 【LWJGL官方教程】Game loops 游戏循环
  2. 烟雨黑帽SEO程序演示:AI智能模板在线制作制作神器-单域名版+多域名版-一键批量制作黑帽程序所使用的单页模板
  3. 毕业设计 嵌入式 stm32指纹识别考勤系统 - 物联网
  4. GPS捕获-Matlab代码
  5. 江苏省计算机学业水平测试模拟软件,基于江苏省普通高中物理学业水平测试的学生在线自主模拟测试系统研发...
  6. Oracle之将常驻内存的程序恢复为默认缓冲池
  7. Nexus部署和使用(笔记)
  8. C语言函数返回值详解
  9. Android——完全自定义 底部弹出支付页面
  10. 价值数十万的免费工具包