scrapy爬虫之crawlspide爬取豆瓣近一周同城活动

简介

本文主要介绍crawlspider爬取豆瓣近一周同城活动。

要点:item/itemloader利用input_processor/output_processor对爬取的数据进行过滤。

实现

为了演示数据过滤,我们只爬取到第二页的数据。

一、定义item

vim items.py
class tongcheng(scrapy.Item):
        #主题
        title = scrapy.Field()
        #时间
        time = scrapy.Field()
        #地址
        address = scrapy.Field(output_processor=Join())
        #票价
        money = scrapy.Field()
        #感兴趣人数
        intrest = scrapy.Field()
        #参加人数
        join = scrapy.Field()

二、定义爬虫

# -*- coding: utf-8 -*-
#爬取豆瓣近一周同城活动
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from scrapy.loader import ItemLoader
from douban.items import tongcheng


class TongchengSpider(CrawlSpider):
    name = 'tongcheng'
    allowed_domains = ['douban.com']
    start_urls = ['https://www.douban.com/location/shenzhen/events/week-all']

    rules = (
        #匹配到第二页
        Rule(LinkExtractor(allow=r'start=10')),
        #获取每页数据
        Rule(LinkExtractor(allow=r'https://www.douban.com/event/\d+/'),callback='parse_item'),
    )

    def parse_item(self, response):
        loader = ItemLoader(item=tongcheng(),selector=response)
        info = loader.nested_xpath('//div[@class="event-info"]')
        info.add_xpath('title','h1[@itemprop="summary"]/text()')
        info.add_xpath('time','div[@class="event-detail"]/ul[@class="calendar-strs"]/li/text()')
        info.add_xpath('address','div[@itemprop="location"]/span[@class="micro-address"]/span[@class="micro-address"]/text()')
        info.add_xpath('money','div[@class="event-detail"]/span[@itemprop="ticketAggregate"]/text()')
        info.add_xpath('intrest','div[@class="interest-attend pl"]/span[1]/text()')
        info.add_xpath('join','div[@class="interest-attend pl"]/span[3]/text()')

        yield loader.load_item()

三、执行爬虫

scrapy crawl toncheng -o tongcheng.json
vi toncheng.json
[
{"money": ["费用:  \n                100元(预售)起\n              "], "address": "深圳  南山区  华侨城创意园 北区C2栋北侧 B10现场", "join": ["65 "], "intrest": ["63 "], "title": ["张玮玮和郭龙“沿江而来”巡演深圳站 @B10现场\n\n\n            "]},
{"money": ["费用:  \n                \n                    93 - 281元\n              "], "address": "深圳  南山文体中心剧院 小剧场 深圳市南山区南山大>道南山文体中心", "join": ["0 "], "intrest": ["1 "], "title": ["2018第五届城市戏剧节 以色列国宝级作家名著改编 王子川自导自演《雅各比和雷弹头》-深圳\n\n\n            "]},
{"money": ["费用:  \n                \n                    95 - 361元\n              "], "address": "深圳  南山文体中心剧院大剧院 南山大道与南头街交汇
处南山文体中心", "join": ["6 "], "intrest": ["10 "], "title": ["【万有音乐系】My Song--Sophie Zelmani 苏菲 · 珊曼妮2018巡回演唱会\n\n\n            "]},
{"money": ["费用:  \n                \n                    263 - 357元\n              "], "address": "深圳  深圳市少年宫剧场 深圳市福田区福中一路市少>年宫", "join": ["67 "], "intrest": ["158 "], "title": ["孟京辉戏剧作品《一个陌生女人的来信》深圳站\n\n\n            "]},
{"money": ["费用:  \n                \n                    170 - 483元\n              "], "address": "深圳  华润深圳湾体育中心"春茧"体育场 深圳市滨>海大道3001号(南山区科苑南路与海德三道交汇处)", "join": ["37 "], "intrest": ["66 "], "title": ["亚洲之巅群星演唱会-深圳站\n                ", "\n\n\n            "]},
......
]

从上面的输出我们看到:
title字段带空格,我们需要的是去除空格的数据;
money字段是[“费用: \n \n 263 - 357元\n “],我们需要的是[”263 - 357元”];

我们需要使用item/itemloader的input_processor/output_processor对数据进行过滤,例如我们已经对address字段使用了output_processor=Join(),我们还需使用MapCompose方法进行过滤。

四、MapCompose

class scrapy.loader.processors.MapCompose(*functions, **default_loader_context)

MapCompose方法接受的数据是可迭代的,数据会经过第一个function进行处理,生成的新的迭代数据会进入第二个函数,以此类推直至所有函数都处理完,生成最终的迭代数据。

1、title字段
title字段需要unicode.strip去处空格,在item中定义如下:

 title = scrapy.Field(input_processor=MapCompose(unicode.strip))

MapCompose通常被用作input_processor,因为我们用selector提取返回的的是可迭代数据。
另外scrapy 会将含有中文的field输出为 unicode字符串形式,因此我们使用unicode.strip来去除空格。

2、money字段
money字段提取的是[“费用: \n \n 263 - 357元\n “],我们只要”263 - 357元”。具体实现如下:

vim items.py
def filter_string(x):
        str = x.split(':')
        return str[1].strip()

money = scrapy.Field(input_processor=MapCompose(filter_string))

filter_string函数的功能就是提取263 - 357元。我们通过MapCompose中调用filter_string,将提取的数据过滤为我们想要的数据。

因此,完整的item代码如下:

# -*- coding: utf-8 -*-
import scrapy
from scrapy.loader.processors import Join, MapCompose, TakeFirst

def filter_string(x):
        str = x.split(':')
        return str[1].strip()

class tongcheng(scrapy.Item):
        title = scrapy.Field(input_processor=MapCompose(unicode.strip))
        time = scrapy.Field()
        address = scrapy.Field(output_processor=Join())
        money = scrapy.Field(input_processor=MapCompose(filter_string))
        intrest = scrapy.Field()
        join = scrapy.Field()

通过定义item后,我们最终提取的数据如下:

[
{"money": ["100元(预售)起"], "address": "深圳  南山区  华侨城创意园 北区C2栋北侧 B10现场", "join": ["65 "], "intrest": ["63 "], "title": ["张玮玮和郭>龙“沿江而来”巡演深圳站 @B10现场"]},
{"money": ["93 - 281元"], "address": "深圳  南山文体中心剧院 小剧场 深圳市南山区南山大道南山文体中心", "join": ["0 "], "intrest": ["1 "], "title": ["2018第五届城市戏剧节 以色列国宝级作家名著改编 王子川自导自演《雅各比和雷弹头》-深圳"]},
{"money": ["95 - 361元"], "address": "深圳  南山文体中心剧院大剧院 南山大道与南头街交汇处南山文体中心", "join": ["6 "], "intrest": ["10 "], "title": ["【万有音乐系】My Song--Sophie Zelmani 苏菲 · 珊曼妮2018巡回演唱会"]},
{"money": ["263 - 357元"], "address": "深圳  深圳市少年宫剧场 深圳市福田区福中一路市少年宫", "join": ["67 "], "intrest": ["158 "], "title": ["孟京辉戏
剧作品《一个陌生女人的来信》深圳站"]},
{"money": ["170 - 483元"], "address": "深圳  华润深圳湾体育中心"春茧"体育场 深圳市滨海大道3001号(南山区科苑南路与海德三道交汇处)", "join": ["37 "], "intrest": ["66 "], "title": ["亚洲之巅群星演唱会-深圳站", ""]},
{"money": ["59元"], "address": "深圳  海上世界文化艺术中心 深圳市南山区蛇口望海路1187号", "join": ["80 "], "intrest": ["116 "], "title": ["设计互联开>幕大展——“数字之维”及“设计的价值”展览"]},
.....
]
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值