返回介绍

10.2 爬取我爱我家二手房房源数据

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

10.2.1 我爱我家网站分析

实战-爬取我爱我家二手房房源数据

为了简单,这里仅爬取我爱我家二手房房源的房产标题、总价及房源所属经纪人这 3 项。打开我爱我家二手房房源页面,分析一下页面特点。

图 10-1 展示了房源标题和总价,但是没有经纪人信息,单击进入房源详情页,如图 10-2 所示。

图 10-1 我爱我家二手房房源列表

图 10-2 我爱我家二手房房源详情页

原来经纪人信息在房源详情页。可以从房源列表页面提取标题和总价信息,然后在详情页提取经纪人信息。再来看一下房源列表页如何翻页。单击页面底部的第 2 页,网址变为 https://bj.5i5j.com/ershoufang/n2/。

很显然,URL 最后的数字代表页数,可以随便换成某页验证一下,也可以验证 https://bj.5i5j.com/ershoufang/n1/就是第一页,这样就找到了网址的规律。为了实现翻页,在 Scrapy 中有两种思路。

(1)直接在 start_urls 中构造网址,毕竟已经找到了 URL 构造规律。

(2)从当前爬取页面中提取下一页的 URL,从而实现翻页爬取。

这里使用第一种方法构造网址列表,实现翻页。

10.2.2 我爱我家爬虫项目实现

下面开始编写代码实现我爱我家爬虫。

第一步,生成项目和爬虫文件。在命令行中执行如下命令生成爬虫项目。

>scrapy startproject pachong2 

然后进入 pachong2 目录,并使用默认模板生成 spider 爬虫文件。

>cd pachong2
>scrapy genspider woaiwojia bj.5i5j.com 

这样就生成了爬虫项目 pachong2,并使用 BasicSpider 模板生成了爬虫文件 woaiwojia.py。

第二步,定义 Item。打开 items.py 定义要爬取的数据。

import scrapy
 
class Pachong2Item(scrapy.Item): 
    apartment = scrapy.Field() 
    total_price = scrapy.Field() 
    agent = scrapy.Field()

这里准备爬取 3 项数据 - apartment、total_price、agent,可以看到定义 item 非常简单。

第三步,编写 spider 文件。打开生成的爬虫文件 woaiwojia.py。

1. 引入 Scrapy 和定义好的 Item

import scrapy
from pachong2.items import Pachong2Item 

2. 用列表推导式生成 start_urls

直接用列表推导式生成准备爬取的 URL 列表。例如这次要爬取前 10 页的房源数据。

class WoaiwojiaSpider(scrapy.Spider):
    name='woaiwojia' 
    allowed_domains=['bj.5i5j.com'] 
    start_urls = ['http://bj.5i5j.com/ershoufang/n' 
+ str(x) + '/' for x in range(1,11)] 

代码中爬虫类及其中的 name 和 allowed_domains,都是模板自动生成的。

3. 定义房源列表页解析方法

Scrapy 请求 start_urls 得到的 response 作为唯一参数,传给了解析函数 parse。在 parse 函数里面,使用嵌套解析,先解析出每套房源代码段,然后从每一代码段中解析每一套房源的数据并写入到 Item 里。这里需要注意如下 3 点。

(1)为了爬取经纪人信息,要解析出房源详情页 URL,然后使用 scrapy.Request 方法继续请求这个 URL,并使用 callback 参数指定回调函数为 parse_detail。scrapy.Request 这个方法主要用来发起 HTTP 请求、获取响应(response),它的第一个参数是请求的 URL,其他常用参数如下。

method:用于指定请求方法,默认为 GET。

headers:指定请求头部,优先级高于 Scrapy 默认的请求头部。

cookies:指定请求发送的 cookies。

meta:request 的 meta 属性,常用于在解析函数之间传递数据。

callback:指定回调函数。

(2)解析出来的 URL 是不完整的相对路径 URL,应使用 response.urljoin 方法构造绝对路径 URL。response.urljoin 方法能将相对网址转换为绝对网址,它会自动提取出当前页面 URL 的主域名,将相对路径 URL 构造成绝对路径 URL。

(3)parse 函数的 Item 里已经保存了从列表页面爬取到的部分数据,因此需要使用 meta 参数在两个解析函数之间传递 Item 数据。

def parse(self, response):
    #提取房源列表数据 
    house_list = response.xpath('//*[@class="pList"]/li')  
    for house in house_list: 
        item = Pachong2Item()   #初始化 Item 
        item['apartment'] = house.xpath( 
          'div[2]/h3/a/text()').extract_first() 
        item['total_price'] = house.xpath( 
          'div[2]/div[1]/div/p[1]/strong/text()').extract_first() 
        #解析并构造详情页 URL 
        detail_url = response.urljoin(house.xpath( 
         'div[2]/h3/a/@href').extract_first())  
    #继续请求详情页 URL,使用 meta 传递已经爬取到的部分数据 
    #使用 callback 指定回调函数 
    yield scrapy.Request(detail_url, meta={'item':item}, 
callback=self.parse_detail)  

4. 定义解析房源详情页面的 parse_detail 函数

def parse_detail(self, response):
    item = response.meta['item']     #接收传递过来的数据 
    #继续向 Item 添加经纪人信息 
    item['agent'] = response.xpath( 
      '//*[@class="daikansty"]/ul/li[2] /h3/a/text()').extract_first() 
yield item    #最后返回 Item 

这段代码首先使用 response.meta['item']接收传递过来的 Item 数据,然后继续向 Item 添加经纪人信息,最后返回 Item。读者应该能注意到,meta 在传递过来的时候是 request 的一个属性,在接收函数这里,response.meta 实质上是 response.request.meta 的快捷方式。

10.2.3 数据的快捷输出

前面我爱我家爬虫代码已经写好了,我们希望能够将爬取到的数据保存下来,以便后续使用。Scrapy 爬虫框架实现了数据的快捷输出 - Feed 输出,它支持多种序列化格式。Scrapy 快捷输出支持的类型有 json、json lines、csv、xml。

例如,现在要启动我爱我家爬虫,并希望保存为 csv 格式,可以在命令行我爱我家项目根目录下执行如下命令。

>scrapy crawl woaiwojia -o wawj.csv 

这里-o 后面是要保存的文件名,因为要保存为 csv 格式,所以文件名的后缀是.csv。如果要保存为 json 格式,可执行如下命令。

>scrapy crawl woaiwojia -o wawj.json 

最后提示一点,如果仅仅保存为这几种常见格式,是没有必要配置 pipeline 的,只需使用本节所讲的快捷保存即可,只有保存到数据库时才需配置 pipeline,第 13 章将讲解如何保存数据到数据库。

本节使用我爱我家这样一个实例演示了使用 BasicSpider 模板编写爬虫的技巧和方法,最后还介绍了数据的快捷保存。在爬取小批量数据时,要经常使用数据的快捷保存。下一节将介绍图片下载和翻页的另一种方法。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

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