【机器学习】北京二手房的现状与未来(一):二手房数据抓取

来源:互联网 发布:网络算命婚姻 编辑:程序博客网 时间:2024/04/28 15:35

  • 一前言
  • 二相关工具
  • 三数据抓取
    • 第一步抓取网页
    • 第二步获取二手房list
    • 第三步获取二手房信息
    • 第四步循环抓取下一页的二手房信息
  • 四结果

一.前言

断断续续接触机器学习至少也将近一年了,之前看过一些ML算法,比如KNN、CNN、SVM、决策树、贝叶斯等等。不过之前一直停留在了解算法的原理,简单地用一下,并没有结合实际应用和真实数据去做分析、预测。因为某些原因,突然就想捣腾一下北京的二手房数据,想分析一下北京二手房现状、以及尽可能地做一些预测等等。于是,一个小工程型的实战项目就开始了。大胆地给这个项目取名叫《北京二手房的现状与未来》,仔细琢磨一下,的确太胆大了,不过自己所做的工作仅仅是用来实战机器学习相关算法,并无其他目的。不禁感叹,北京房价确实很贵。

二.相关工具

目前只完成了数据抓取的工作,后续工作完成后再补充。
1.数据来源:某客
2.python

三.数据抓取

因为我对python语法、爬虫和正则表达式都不太熟悉,都是现用现学,现学现用,所以给的代码仅供参考,有任何问题欢迎大家指正。
对于二手房属性,对于后期不同的需求,一共考虑了16个因素:中介公司、地址-区、地址-地名、地址-街道、小区名、X室、X厅、X卫、装修程度、面积、单价、年代、朝向、类型、楼层、地铁房(是or不是)

第一步:抓取网页

代码如下:

def getHTML(self,url):    try:        request = urllib2.Request(url)        response = urllib2.urlopen(request)        return response.read().decode('utf-8')    except urllib2.URLError, e:        if hasattr(e,"reason"):           print u"连接失败,错误原因",e.reason           return None

获取的HTML页面如下:
这里写图片描述

第二步:获取二手房list

从上面的HTML中可以看到,每一个”li”标签就是一个二手房的信息,那么就可以先获得当前页中所有二手房。

# 获取房屋信息list    def getHouseList(self,page):        pattern = re.compile(u'<li class="list-item.*?" data-from="">(.*?)</li>')        houseList = re.findall(pattern,page)        if houseList:            return houseList        else:            return None

第三步:获取二手房信息

HTML页面的li标签内部代码如下
这里写图片描述
由于从”li“标签中还无法获取完整的16个因素,所以我选择了从“li”标签中仅仅获取中介公司和详情页链接,然后通过链接进入到二手房的详情页,进一步获得其他的15个因素,最后将二手房的信息写入txt文件中。
其中详情页HTML如下,在获取这些数据时,我是先用正则表达式匹配三个列,然后再分别在每一列中,进行相关数据的匹配。
这里写图片描述

#将list写入文件    def writeData(self,f,list):        for item in list:            f.write(item)            f.write('   ')        f.write('\n')    def append2HI(self,col,HI):        len = col.lastindex        for i in range(1,len+1):            if col.group(i) is not None:                  HI.append(col.group(i))            else:                HI.append('无')# 处理房屋list,获取单个房屋的信息    def getHouseInfo(self,houseList):        if houseList is not None:            f=open('hello.txt','a')            for house in houseList:                HI = []                #Step 1:中介、详情链接                pattern = re.compile(u'<div class="house-title">.*?<a data-from="" data-company="(.*?)" .*? href="(.*?)" .*?>.*?</div>')                result = re.search(pattern,house)                if result.group(1):                    HI.append(result.group(1))                else:                    HI.append('无')                # Step 2:是否地铁房                pattern = re.compile(u'<div class="details-item details-bottom">.*?<span>地铁房</span>.*?</div>')                railway = re.search(pattern,house)                if railway:                    HI.append('1')                else:                    HI.append('0')                # Step 3:通过详情链接获得房屋详情                print result.group(2).strip()                request = urllib2.Request(result.group(2).strip())                response = urllib2.urlopen(request)                page = response.read().decode('utf-8')                pattern = re.compile(u'<div class="houseInfo-detail clearfix"><div class="first-col detail-col">(.*?)</div><div class="second-col detail-col">(.*?)</div><div class="third-col detail-col">(.*?)</div></div>')                page = re.sub(re.compile('\n|\t|\r'),'',page)                print '匹配中ing\n'                info = re.search(pattern,page)                if info:                    pattern = re.compile(u'<dl><dt>小区:</dt><dd><a.*?>(.*?)</a>.*?</dd></dl><dl><dt>位置:</dt><dd><p.*?><a.*?>(.*?)</a>-<a.*?>(.*?)</a>-(.*?)</p>.*?</dd></dl><dl><dt>年代:</dt><dd>(.*?)年</dd></dl><dl><dt>类型:</dt><dd>(.*?)</dd></dl>')                    first_col = re.search(pattern,info.group(1))                    if first_col:                        self.append2HI(first_col,HI)                    pattern = re.compile(u'<dl><dt>房型:</dt><dd>(.*?)室(.*?)厅(.*?)卫</dd></dl><dl><dt>面积:</dt><dd>(.*?)平方米</dd></dl><dl><dt>朝向:</dt><dd>(.*?)</dd></dl><dl><dt>楼层:</dt><dd>(.*?)</dd></dl>')                    second_col = re.search(pattern,info.group(2))                    if second_col:                        self.append2HI(second_col,HI)                    pattern = re.compile(u'<dl><dt>装修程度:</dt><dd>(.*?)</dd></dl><dl><dt>房屋单价:</dt><dd>(.*?)元/m²</dd></dl><dl><dt>.*?我要贷款</a></dd></dl>')                    third_col = re.search(pattern,info.group(3))                    if third_col:                        self.append2HI(third_col,HI)                HI.append(result.group(2))                self.writeData(f,HI)            f.close()        else:            print '数据为空'

第四步:循环抓取下一页的二手房信息

解决”下一页“的问题采取的方式是,获取下一页上的href,如果href存在就抓取href对应页面上的二手房信息,直到href不存在,这也是根据某客的HTML代码结构想到的方式。于是采用了一个do{}while();形式的代码完成的,大概如下:

 while True:        url =  '第一页的链接'         # 获取下一页的链接        pattern = re.compile(u'<i class="aDotted">...</i>.*?<a href="(.*?)" class="aNxt">下一页 &gt;</a>')        nextClass = re.search(pattern,page)        if nextClass is None: #href不存在时,结束            break        url = nextClass.group(1)# href存在时,更新url,循环抓取数据

四.结果

最后获得了6901条数据,除去一些匹配有误的数据粗略估计有一百条左右,那么有效数据预计有6800条,这也为后续工作提供了数据基础。
这里写图片描述

0 0