数据挖掘(六):用XPath爬取链家网房价数据

标签: 数据挖掘 xpath 房价 | 发表时间:2017-07-20 11:28 | 作者:czl389
出处:http://blog.csdn.net

准备工作

编写爬虫前的准备工作,我们需要导入用到的库,这里主要使用的是requests和lxml两个。还有一个Time库,负责设置每次抓取的休息时间。

  import requests
import requests
import time
from lxml import etree

抓取列表页

开始抓取前当然应该了解一下目标网站URL结构咯。

链家网的二手房列表页面共有100个,URL结构为
https://nj.lianjia.com/ershoufang/pg2/
其中

  • nj表示城市
  • /ershoufang/是频道名称
  • pg2是页面码。

我们要抓取的是南京的二手房频道,所以前面的部分不会变,属于固定部分,后面的页面码需要在1-100间变化,属于可变部分。将URL分为两部分,前面的固定部分赋值给url,后面的可变部分使用for循环遍历页面。

  #设置列表页URL的固定部分
url='http://nj.lianjia.com/ershoufang/'
#设置页面页的可变部分
page=('pg')
这里提一个小小的醒,我们最好在http请求中设置一个头部信息,否则很容易被封ip。头部信息网上有很多现成的,也可以使用httpwatch等工具来查看。
  #设置请求头部信息
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11',
'Accept':'text/html;q=0.9,*/*;q=0.8',
'Accept-Charset':'ISO-8859-1,utf-8;q=0.7,*;q=0.3',
'Accept-Encoding':'gzip',
'Connection':'close',
'Referer':'http://www.baidu.com/link?url=_andhfsjjjKRgEWkj7i9cFmYYGsisrnm2A-TN3XZDQXxvGsM9k9ZZSnikW2Yds4s&wd=&eqid=c3435a7d00146bd600000003582bfd1f'
}
以抓取前10个页面为例,我们使用for循环生成1-10的数字,转化格式后与前面的URL固定部分拼成要抓取的URL。这里我们设置每两个页面间隔0.5秒。抓取到的页面保存在html中。
  #循环抓取列表页信息
for i in range(1,11):
    if i == 1:
        i=str(i)
        a=(url+page+i+'/')
        r=requests.get(url=a,headers=headers)
        html=r.content
    else:
        i=str(i)
        a=(url+page+i+'/')
        r=requests.get(url=a,headers=headers)
        html2=r.content
        html = html + html2
    #每次间隔0.5秒
    time.sleep(0.5)

页面解析

页面抓取的工作算是完成了,内容在html中,下一步就要进行页面解析了。我们使用lxml库的xpath方法对页面进行解析。

  • 注意指定解析器的编码格式
  encoding=requests.get(url,headers=headers).encoding
lj=etree.HTML(html,parser=etree.HTMLParser(encoding=encoding))

完成页面解析后就可以对页面中的关键信息进行提取了。下面我们分别对房源的总价,房源信息和关注度三部分进行提取。
把页面div标签中class=priceInfo的部分提取出来,并使用for循环将其中每个房源的总价数据存在tp中。

相关html源码如下:

    <div class="priceInfo"><div class="totalPrice"><span>360</span>万</div><div class="unitPrice" data-hid="103101449315" data-rid="1411044934948" data-price="39353"><span>单价39353元/平米</span></div></div>

可以看出总价数据存放在div子节点span的string元素里,用下面的xpath表达式把所有totalPrice解析出来

  #提取房源总价
price=lj.xpath('//div[@class="priceInfo"]')

tp=[]
for a in price:
    totalPrice=a.xpath('.//span/text()')[0]
    tp.append(totalPrice)
抽取打印前10条房源总价信息:
  for p in tp[:10]:
    print p
  480
360
190
335
182
210
466
86
308
163

提取房源信息和关注度的方法与提取房源价格的方法类似,下面是具体的代码,房源信息存储在hi中,关注度存储在fi中。

与房屋信息相关html源码如下:

   <div class="houseInfo"><span class="houseIcon"></span><a href="https://nj.lianjia.com/xiaoqu/1411044934948/" target="_blank" data-log_index="2" data-el="region">银城东苑紫荆苑 </a> | 2室2厅 | 91.48平米 | 南 | 精装</div>

用如下xpath语句将其解析出来

  #提取房源信息
houseInfo=lj.xpath('//div[@class="houseInfo"]')

hi=[]
for b in houseInfo:
    house=b.xpath('.//text()')[0]+b.xpath('.//text()')[1]
    hi.append(house)
抽取打印前10条房屋信息:
  for i in hi[:10]:
    print i
  龙凤花园隽凤园  | 4室2厅 | 112.36平米 | 南 北 | 简装 | 无电梯
银城东苑紫荆苑  | 2室2厅 | 91.48平米 | 南 | 精装
锁金三村  | 2室1厅 | 61.59平米 | 南 北 | 其他 | 无电梯
文思苑  | 2室2厅 | 95.79平米 | 南 北 | 其他 | 有电梯
蓝岸尚城  | 2室2厅 | 49.01平米 | 南 | 精装
百家湖国际花园  | 2室1厅 | 78.12平米 | 南 | 其他 | 有电梯
万科光明城市西苑  | 2室2厅 | 96.11平米 | 南 北 | 精装
万达紫金明珠  | 1室1厅 | 38.64平米 | 北 | 简装 | 有电梯
文化名园上筑园  | 3室2厅 | 123.22平米 | 南 | 简装 | 有电梯
金龙花园  | 2室1厅 | 61.73平米 | 南 北 | 简装 | 无电梯

类似的,再提取关注度信息:

  #提取房源关注度
followInfo=lj.xpath('//div[@class="followInfo"]')

fi=[]
for c in followInfo:
    follow=c.xpath('./text()')[0]
    fi.append(follow)
抽取打印前10条房屋信息:
  for i in fi[:10]:
    print fi[0]
  158人关注 / 共59次带看 / 6个月以前发布
158人关注 / 共59次带看 / 6个月以前发布
158人关注 / 共59次带看 / 6个月以前发布
158人关注 / 共59次带看 / 6个月以前发布
158人关注 / 共59次带看 / 6个月以前发布
158人关注 / 共59次带看 / 6个月以前发布
158人关注 / 共59次带看 / 6个月以前发布
158人关注 / 共59次带看 / 6个月以前发布
158人关注 / 共59次带看 / 6个月以前发布
158人关注 / 共59次带看 / 6个月以前发布

清洗数据并整理到数据表中

我们将之前爬取到的信息进行汇总,并导入pandas之中生成数据表。便于后面的分析。

  #导入pandas库
import pandas as pd
#创建数据表
house=pd.DataFrame({'totalprice':tp,'houseinfo':hi,'followinfo':fi})
#查看数据表的内容
house.head()
followinfo houseinfo totalprice
0 158人关注 / 共59次带看 / 6个月以前发布 龙凤花园隽凤园 | 4室2厅 | 112.36平米 | 南 北 | 简装 | 无电梯 480
1 29人关注 / 共22次带看 / 22天以前发布 银城东苑紫荆苑 | 2室2厅 | 91.48平米 | 南 | 精装 360
2 114人关注 / 共132次带看 / 4个月以前发布 锁金三村 | 2室1厅 | 61.59平米 | 南 北 | 其他 | 无电梯 190
3 11人关注 / 共32次带看 / 18天以前发布 文思苑 | 2室2厅 | 95.79平米 | 南 北 | 其他 | 有电梯 335
4 156人关注 / 共106次带看 / 2个月以前发布 蓝岸尚城 | 2室2厅 | 49.01平米 | 南 | 精装 182

很尴尬的是,大家看得到,很多信息是糊在一块的,不能直接使用,所以咱们再做一些数据提取和清洗的工作。如房源信息,在表中每个房源的小区名称,户型,面积,朝向等信息都在一个字段中,无法直接使用。需要先进行分列操作。这里的规则比较明显,每个信息间都是以竖线分割的,因此我们只需要以竖线进行分列即可。

  #对房源信息进行分列
houseinfo_split = pd.DataFrame((x.split('|') for x in house.houseinfo),index=house.index,columns=['xiaoqu','huxing','mianji','chaoxiang','zhuangxiu','dianti'])
现在再来看看我们整理好的数据
  #查看分列结果
houseinfo_split.head()
xiaoqu huxing mianji chaoxiang zhuangxiu dianti
0 龙凤花园隽凤园 4室2厅 112.36平米 南 北 简装 无电梯
1 银城东苑紫荆苑 2室2厅 91.48平米 精装 None
2 锁金三村 2室1厅 61.59平米 南 北 其他 无电梯
3 文思苑 2室2厅 95.79平米 南 北 其他 有电梯
4 蓝岸尚城 2室2厅 49.01平米 精装 None

把拆分后的数据拼接回原始数据中

  #将分列结果拼接回原数据表
house=pd.merge(house,houseinfo_split,right_index=True, left_index=True)
house.head()
followinfo houseinfo totalprice xiaoqu huxing mianji chaoxiang zhuangxiu dianti
0 158人关注 / 共59次带看 / 6个月以前发布 龙凤花园隽凤园 | 4室2厅 | 112.36平米 | 南 北 | 简装 | 无电梯 480 龙凤花园隽凤园 4室2厅 112.36平米 南 北 简装 无电梯
1 29人关注 / 共22次带看 / 22天以前发布 银城东苑紫荆苑 | 2室2厅 | 91.48平米 | 南 | 精装 360 银城东苑紫荆苑 2室2厅 91.48平米 精装 None
2 114人关注 / 共132次带看 / 4个月以前发布 锁金三村 | 2室1厅 | 61.59平米 | 南 北 | 其他 | 无电梯 190 锁金三村 2室1厅 61.59平米 南 北 其他 无电梯
3 11人关注 / 共32次带看 / 18天以前发布 文思苑 | 2室2厅 | 95.79平米 | 南 北 | 其他 | 有电梯 335 文思苑 2室2厅 95.79平米 南 北 其他 有电梯
4 156人关注 / 共106次带看 / 2个月以前发布 蓝岸尚城 | 2室2厅 | 49.01平米 | 南 | 精装 182 蓝岸尚城 2室2厅 49.01平米 精装 None

使用相同的方法对房源关注度字段进行分列和拼接操作。这里的分列规则是斜杠。

  #对房源关注度进行分列
followinfo_split = pd.DataFrame((x.split('/') for x in house.followinfo),index=house.index,columns=['guanzhu','daikan','fabu'])
#将分列后的关注度信息拼接回原数据表
house=pd.merge(house,followinfo_split,right_index=True, left_index=True)
house.head()
followinfo houseinfo totalprice xiaoqu huxing mianji chaoxiang zhuangxiu dianti guanzhu daikan fabu
0 158人关注 / 共59次带看 / 6个月以前发布 龙凤花园隽凤园 | 4室2厅 | 112.36平米 | 南 北 | 简装 | 无电梯 480 龙凤花园隽凤园 4室2厅 112.36平米 南 北 简装 无电梯 158人关注 共59次带看 6个月以前发布
1 29人关注 / 共22次带看 / 22天以前发布 银城东苑紫荆苑 | 2室2厅 | 91.48平米 | 南 | 精装 360 银城东苑紫荆苑 2室2厅 91.48平米 精装 None 29人关注 共22次带看 22天以前发布
2 114人关注 / 共132次带看 / 4个月以前发布 锁金三村 | 2室1厅 | 61.59平米 | 南 北 | 其他 | 无电梯 190 锁金三村 2室1厅 61.59平米 南 北 其他 无电梯 114人关注 共132次带看 4个月以前发布
3 11人关注 / 共32次带看 / 18天以前发布 文思苑 | 2室2厅 | 95.79平米 | 南 北 | 其他 | 有电梯 335 文思苑 2室2厅 95.79平米 南 北 其他 有电梯 11人关注 共32次带看 18天以前发布
4 156人关注 / 共106次带看 / 2个月以前发布 蓝岸尚城 | 2室2厅 | 49.01平米 | 南 | 精装 182 蓝岸尚城 2室2厅 49.01平米 精装 None 156人关注 共106次带看 2个月以前发布

然后再删除原先的列

  house=house.drop(['houseinfo','followinfo'],axis=1)
print "共采集"+str(len(house))+"条房源信息"
house.head()
共采集300条房源信息
totalprice xiaoqu huxing mianji chaoxiang zhuangxiu dianti guanzhu daikan fabu
0 480 龙凤花园隽凤园 4室2厅 112.36平米 南 北 简装 无电梯 158人关注 共59次带看 6个月以前发布
1 360 银城东苑紫荆苑 2室2厅 91.48平米 精装 None 29人关注 共22次带看 22天以前发布
2 190 锁金三村 2室1厅 61.59平米 南 北 其他 无电梯 114人关注 共132次带看 4个月以前发布
3 335 文思苑 2室2厅 95.79平米 南 北 其他 有电梯 11人关注 共32次带看 18天以前发布
4 182 蓝岸尚城 2室2厅 49.01平米 精装 None 156人关注 共106次带看 2个月以前发布

好了,这就是咱们对链家网的部分数据爬取过程了。
跃跃欲试的宝宝们何不自己动手,再解析一些内容试试。

作者:czl389 发表于2017/7/20 15:58:36 原文链接
阅读:54 评论:0 查看评论

相关 [数据挖掘 xpath 房价] 推荐:

数据挖掘(六):用XPath爬取链家网房价数据

- - CSDN博客推荐文章
编写爬虫前的准备工作,我们需要导入用到的库,这里主要使用的是requests和lxml两个. 还有一个Time库,负责设置每次抓取的休息时间. 开始抓取前当然应该了解一下目标网站URL结构咯. 链家网的二手房列表页面共有100个,URL结构为. /ershoufang/是频道名称. 我们要抓取的是南京的二手房频道,所以前面的部分不会变,属于固定部分,后面的页面码需要在1-100间变化,属于可变部分.

Xpath语法

- - ITeye博客
XPath 使用路径表达式来选取 XML 文档中的节点或节点集. 节点是通过沿着路径 (path) 或者步 (steps) 来选取的. 我们将在下面的例子中使用这个 XML 文档. XPath 使用路径表达式在 XML 文档中选取节点. 节点是通过沿着路径或者 step 来选取的. 下面列出了最有用的路径表达式:.

XPath 教程

- - Web前端 - ITeye博客
XPath 是一门在 XML 文档中查找信息的语言. XPath 可用来在 XML 文档中对元素和属性进行遍历. XPath 是 W3C XSLT 标准的主要元素,并且 XQuery 和 XPointer 同时被构建于 XPath 表达之上. 因此,对 XPath 的理解是很多高级 XML 应用的基础.

数据挖掘是神马?

- - 互联网分析
1、数据挖掘需要‘神马样’的流程.  2、哥,有没有详细点的,来个给力的. 4、数据在统计意义上有哪些类型. 9、知道这些工具不知道如何在工作中用呀. 11、还有没有更人性化、智能化的展现. 12、上面这图看起来很给力,背后很复杂吧.  16、转载的留个来源 ,毕竟是我辛苦收集和想出来的,谢谢. 忘记“大数据”,从“中数据”开始.

这就是数据挖掘

- - 互联网分析
当今数据库的容量已经达到上万亿的水平(T)— 1,000,000,000,000个字节. 在这些大量数据的背后隐藏了很多具有决策意义的信息,那么怎么得到这些“知识”呢. 也就是怎样通过一颗颗的树木了解到整个森林的情况. 计 算机科学对这个问题给出的最新回答就是:数据挖掘,在“数据矿山”中找到蕴藏的“知识金块”,帮助企业减少不必要投资的同时提高资金回报.

关于数据挖掘

- - 牛国柱
以下内容来自网络,关于数据挖掘的一些最基本的知识. 数据挖掘是对一系列数据进行分析和挖掘的方法的统称,在精准营销领域,最常用的数据挖掘方法主要包括以下三类:分类、聚类、关联. 分类(Classify)属于预测性模型. 分类模型的构建需要“训练样本”,训练样本中的每一个个体的类别必须是明确的. 分类模型的特征变量一般称为“自变量”,又叫“预测变量”,类别变量称为“目标变量”.

[译]XPath和CSS选择器

- - 博客园_首页
原文: http://ejohn.org/blog/xpath-css-selectors. 我认为将这两种选择器的写法做一个比较是很有价值的.. 所有P元素的第一个子元素. 从语法上看,我非常惊讶这两种选择器在某些情况下的相似性,尤其是'>'和'/'两者之间.虽然他们并不总是有着相同的功能(XPath中要取决于正在使用的轴),但通常情况下他们指的都是某个父元素的子元素.还有,空白符' '和'//'都意味着当前元素的所有后代元素.最后是星号'*',类似于通配符,表示所有元素,而不管是哪种标签名..

Xpath语法格式整理

- - 行业应用 - ITeye博客
Xpath语法格式整理. 经常在工作中会使用到XPath的相关知识,但每次总会在一些关键的地方不记得或不太清楚,所以免不了每次总要查一些零碎的知识,感觉即很烦又浪费时间,所以对XPath归纳及总结一下. 在这篇文章中你将能学习到:. XPath 路径表达式详解. XPath在DOM,XSLT及XQuery中的应用.

数据挖掘与Taco Bell编程

- everfly - 译言-每日精品译文推荐
来源Data Mining and Taco Bell Programming. Programmer Ted Dziuba suggests an alternative to traditional program that he called "Taco Bell Programming." The Taco Bell chain creates multiple menu items from about eight different ingredients.

使用Weka进行数据挖掘

- - 搜索研发部官方博客
数据挖掘、机器学习这些字眼,在一些人看来,是门槛很高的东西. 诚然,如果做算法实现甚至算法优化,确实需要很多背景知识. 但事实是,绝大多数数据挖掘工程师,不需要去做算法层面的东西. 他们的精力,集中在特征提取,算法选择和参数调优上. 那么,一个可以方便地提供这些功能的工具,便是十分必要的了. 而weka,便是数据挖掘工具中的佼佼者.