Python爬虫抓取链家二手房数据

1年前 (2024-04-27)
本节使用 Python 爬虫库完成链家二手房(https://bj.lianj网站站点" rel="nofollow" />

页:https://bj.lianj网站站点" rel="nofollow" />

<div class="info clear">

<div class="title"><a class="" href="https://bj.lianj网站站点" rel="nofollow" />

<div class="positionInfo">..</div>

<div class="address">...</div>

<div class="priceInfo">...</div>

而每个页面中都包含 30 个房源,因此我们要匹配以下节点的父节点或者先辈节点,从而确定 Xpath 基准表达式:

<div class="info clear"></div>

通过页面结构分析可以得出每页的 30 个房源信息全部包含以下节点中:

<ul class="sellListContent" log-mod="list">

<li class="clear LOGVIEWDATA LOGCLICKDATA">

房源信息..

</li>

</ul>

接下来,使用调试工具定位上述元素,然后滚动鼠标滑。这时候奇的一幕出现了,你会发现li标签的class属性值发生了变化,其结果如下:

<ul class="sellListContent" log-mod="list">

<li class="clear LOGCLICKDATA">

房源信息..

</li>

</ul>

发生变化的原因是由于 JS 事件触发导致的。因此就需要去页面的源码页进行匹配。

下面使用Ctrl+F分别对 class 变化前后的属性值进行检索,发现源码页只存在如下属性:

class="clear LOGVIEWDATA LOGCLICKDATA"

因此 Xpath 基准表达式如下所示:

//ul[@class="sellListContent"]/li[@class="clear LOGVIEWDATA LOGCLICKDATA"]

2) 确定抓取信息的表达式

根据页面元素结构确定待抓取信息的 Xpath 表达式,分别如下:

小区名称:name_list=h.xpath('.//a[@data-el="region"]/text()')

房屋介绍:info_list=h.xpath('.//div[@class="houseInfo"]/text()')

地址信息:address_list=h.xpath('.//div[@class="positionInfo"]/a/text()')

单价信息:price_list=h.xpath('.//div[@class="unitPrice"]/span/text()')

其中房屋介绍,主要包含了以下信息:

<div class="address">

<div class="houseInfo"><span class="houseIcon"></span>2室1厅 | 88.62平米 | 北 南 | 简装 | 顶层(共6层) | 2004年建 | 板楼</div>

</div>

因此,匹配出的 info_list 列表需要经过处理才能得出我们想要的数据,如下所示:

#户型+面积+方位+是否精装+楼层+... ['2室1厅 | 88.62平米 | 北 南 | 简装 | 顶层(共6层) | 2004年建 | 板楼']

info_list=h.xpath('.//div[@class="houseInfo"]/text()')

if info_list:

#处理列表数据

L=info_list[0].split('|')

# ['2室1厅 ', ' 88.62平米 ', ' 北 南 ', ' 简装 ', ' 顶层(共6层) ', ' 2004年建 ', ' 板楼']

if len(L) >= 5:

item['model']=L[0].strip()

item['area']=L[1].strip()

item['direction']=L[2].strip()

item['perfect']=L[3].strip()

item['floor']=L[4].strip()

3) 提高抓取效率

为了提高网页信息的抓取质量,减小网络波动带来的响应,我们可以设置一个规则:在超时时间内(3秒),在该时间内对于请求失败的页面尝试请求三次,如果均未成功,则抓取下一个页面。

requests.get() 方法提供了 timeout 参数可以用来设置超时时间,此方法还提供了其他实用性参数,比如 auth(用户认证)、veryify(证书认证)、proxies(设置代理 IP),这在后续内容中会做相应介绍。

编写程序代码

通过上述分析得出了所有的 Xpath 表达式,下面开始编写爬虫程序,代码如下:

#coding:utf8

import requests

import random

from lxml import etree

import time

#提供ua信息的的包

from fake_useragent import UserAgent

class LinajiaSpider(object):

def __init__(self):

self.url='https://bj.lianj网站站点" rel="nofollow" />

{'name': '玉竹园 ', 'model': '2室1厅', 'area': '88.62平米', 'direction': '北 南', 'perfect': '简装', 'floor': '顶层(共6层)', 'address': '玉竹园', 'total_list': '225', 'price_list': '单价25390元/平米'}

{'name': '摩卡空间 ', 'model': '2室1厅', 'area': '71.95平米', 'direction': '东南', 'perfect': '简装', 'floor': '高楼层(共17层)', 'address': '摩卡空间', 'total_list': '372', 'price_list': '单价51703元/平米'}

{'name': '长城 ', 'model': '1室1厅', 'area': '52.73平米', 'direction': '西', 'perfect': '精装', 'floor': '22层', 'address': '长城', 'total_list': '235', 'price_list': '单价44567元/平米'}

{'name': '牛街西里 ', 'model': '3室1厅', 'area': '102.6平米', 'direction': '东北', 'perfect': '其他', 'floor': '中楼层(共20层)', 'address': '牛街西里', 'total_list': '815', 'price_list': '单价79435元/平米'}

{'name': '新安里 ', 'model': '1室2厅', 'area': '51.56平米', 'direction': '南 北', 'perfect': '精装', 'floor': '顶层(共6层)', 'address': '新安里', 'total_list': '197', 'price_list': '单价38208元/平米'}

{'name': '龙华园 ', 'model': '2室1厅', 'area': '67.73平米', 'direction': '南 北', 'perfect': '简装', 'floor': '顶层(共6层)', 'address': '龙华园', 'total_list': '342', 'price_list': '单价50495元/平米'}

...