返回介绍

4.1 Q 房网爬虫实例

发布于 2025-04-21 19:15:26 字数 4907 浏览 0 评论 0 收藏

爬虫实战-爬取 Q 房网

前 3 章已经介绍了编写简单爬虫的基础知识,这一节通过爬虫实例讲解爬取一个具体网站的各种技巧。

4.1.1 网站页面分析

本节爬取的目标网站是深圳 Q 房网(http://shenzhen.qfang.com/),要爬取二手房房源的小区、户型、面积、区域、总价及房源特色,并把这些信息保存到计算机上。

要爬取一个网站,首先要仔细分析它的页面特点和 URL 构造规律。图 4-1 所示为 Q 房网(深圳)的二手房页面。

图 4-1 Q 房网(深圳)的二手房页面

可以看到每页上有 30 套房源,单击底部的翻页跳转到房源第二页,URL 变为 http://shenzhen.qfang.com/sale/f2。继续单击第三页,看到 URL 变为 http://shenzhen.qfang.com/sale/f3。

读者应该看得出来二手房页面 URL 的构造特点,那就是跟在 f 后面的是页码。如果想验证这个规律,可以直接将 URL 中的页码改为某一个数字,例如改为 54,看到打开的页面的确是第 54 页。那么第一页是否也满足这样的规律呢?打开 http://shenzhen.qfang.com/sale/f1。

可以看到这正是二手房房源的首页。至此,已经找到了 URL 的构造规律,可以利用这个规律对多个页面进行爬取。这次为了简单,可以爬取 10 页,也就是 300 条房源信息。

要爬取的数据包括二手房房源的小区、户型、面积、区域、总价及房源特色,下面分析页面,看看这些数据分布在页面的什么位置。图 4-2 所示的是页面中的一套房源。

图 4-2 页面中的一套房源

从这一条房源信息很容易看到,房源题目包含小区名称和房源特色介绍,下面一行包含户型和面积,单价和总价在靠右边的位置,板块在更下一行。从这里可以看出,房源列表页面已经包含所需要爬取的所有数据,因此爬虫只需要爬取房源列表页面即可,不需要爬取房源详情页面。

页面分析到此结束,下面可以开始编写代码了。

4.1.2 编写 Q 房网二手房房源爬虫代码

首先导入 Requests 库和 Lxml 库。这里准备把数据保存为 csv 格式,因此还需要导入 csv 模块。为了控制爬行速度,还需要导入 time 模块,控制爬行速度的目的主要是防止被 Q 房网的服务器反爬虫禁止。

from lxml import etree
import requests 
import csv 
import time 

然后定义抓取函数。这里专门定义一个爬取和解析数据的函数。在第 2 章爬虫基础中曾讲过,服务器会通过读取请求头部的用户代理(User Agent)信息,来判断这个请求是正常的浏览器还是爬虫。为防止被服务器反爬虫禁止,函数里还要定义一个头部。

def spider():
    #定义爬虫头部 
    headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64)\ 
               AppleWebKit/537.36 (KHTML, like Gecko) 
               Chrome/46.0.2490.80 Safari/537.36'}  
#这里使用 for 循环构造前 10 页 URL 地址并 GET 请求下来 
#为了防止爬行速度过快,在每一次 GET 后,等待 2 秒 
    pre_url = 'http://shenzhen.qfang.com/sale/f' 
    for x in range(1,11): 
        html = requests.get(pre_url+str(x), headers=headers) 
        time.sleep(2) 
        #用获取到的页面初始化 etree,得到一个 selector, 
        #然后在这个 selector 上使用 XPath 提取数据 
selector = etree.HTML(html.text) 

到这里已经爬取了房源列表页,每一个房源列表页上有 30 套(也可能少于 30 套,如最后一页)房源,每一套房源上都包含一组所需要的信息。提取出这些房源数据有一个常用技巧:先提取每套房源整体的代码段,然后从中解析出每套房源的具体信息。也就是说,应该先获得每一套房源的 HTML 源码,然后从这一段 HTML 源码里面解析出来这套房源的详细信息。

先来获取每一套房源的代码段。可以借助 Chrome 浏览器的“检查”功能,看看如何获取每一套房源的代码段。在页面空白处单击右键,在弹出的菜单中选择“检查”,使用左上角的选择箭头选中一套房源,如图 4-3 所示。

图 4-3 查看每套房源的 XPath 路径

很明显,这里有很多<li>标签,把鼠标移动到第二个<li>标签,就会发现第二套房源信息变为蓝色,这样就知道每一个<li>标签里就是一套房源的代码。使用 Chrome 浏览器复制第一个<li>标签的 XPath,就会得到类似下面的 XPath 路径。

//*[@id="cycleListings"]/ul/li[1] 

如果把路径<li>后面的序号去掉,就得到了<ul>标签下所有<li>标签的路径,可以在 HTML 代码中查看确认一下<ul>标签下的所有<li>标签是否均是房源、没有其他内容的<li>标签。经过确认,可以得到房源列表的 XPath 路径为//*[@id="cycleListings"]/ul/li。

使用这个 XPath 路径提取出来的,就是这一页中每套房源的代码段组成的一个列表,然后对这个列表做一个循环,在每一套房源的代码片段上再次使用 Xpath,取出每套房源的具体信息,按这个思路继续写代码。

        #先获取房源列表
        house_list = selector.xpath("//*[@id='cycleListings']/ul/li")   
        for house in house_list: 
            apartment = house.xpath("div[1]/p[1]/a/text()")[0] 
            house_layout = house.xpath("div[1]/p[2]/span[2]/text()")[0] 
            area = house.xpath("div[1]/p[2]/span[4]/text()")[0] 
            region = house.xpath("div[1]/p[3]/span[2]/a[1]/text()")[0] 
total_price = house.xpath("div[2]/span[1]/text()")[0]  

这里要注意,在 for 循环里使用的 XPath 路径是相对路径,也就是取出的<li>标签下的路径。要写出正确的相对路径有一个技巧:从 Chrome 浏览器里面复制的第一套房源代码段的 XPath 路径如下。

//*[@id="cycleListings"]/ul/li[1] 

复制出的这套房源户型的 XPath 路径如下。

//*[@id="cycleListings"]/ul/li[1]/div[1]/p[2]/span[2] 

通过比对这两个路径,很容易知道户型在房源码中的 XPath 相对路径是 div[1]/p[2]/span[2]。

这样就很容易写出代码段中的相对 XPath 路径。

继续把爬取的数据构造成一个 list,然后使用 data_writer 这个保存函数写入计算机中。

item = [apartment, house_layout, area, region, total_price]
data_writer(item)  #保存数据 
print('正在抓取', xiaoqu) 

函数最后使用 print 打印出正在抓取的小区名称,作为爬虫的运行提示。

4.1.3 保存爬取到的信息

可以把获取到的每一套房源信息组成一个 list,保存到 csv 文件里,为了方便复用,这里直接写一个保存函数 data_writer,这个函数接受一个列表,然后使用 csv 的 writerow 方法写入一条记录。

def data_writer(item):
    with open('qfang_ershoufang.csv', 'a',  
              encoding='utf-8', newline='') as csvfile: 
        writer = csv.writer(csvfile) 
writer.writerow(item) 

首先以追加(a)的方式打开一个 csv 文件(如果没有,系统会新建一个),设置编码方式为 encoding='utf-8',为了防止 csv 文件在每次打开添加数据的时候插入空行,设置 newline=''。

最后编写主函数。

if __name__ == '__main__':
spider() 

以上就是一个非常简单的爬虫,读者可以在 PyCharm 中运行这段爬虫代码,查看一下爬取的结果。

通过这个例子的学习,读者应该对编写简单爬虫有了一个大概的思路,可以尝试爬取其他相似的栏目做练习,如爬取 Q 房网的租房栏目的房源信息等。最后要提醒读者的是,在爬取一个网站的时候,应该尽量克制爬取速度,一方面是防止被服务器发现,另一方面,爬取行为不可以占用太多服务器资源而影响网站正常用户的访问。因此,可以在代码中使用 time.sleep() 进行等待时间控制,人为地控制爬虫的爬取速度。

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。