腊月的季节

scrapy爬虫技术五

CrawlSpider

class scrapy.contrib.spiders.CrawlSpider
爬取一般网站常用的都是这个spider。他定义了一些规则(rule)来提供跟进link的方便机制。一个spider不可能适用所有场景,但其对很多情况都适用。所以你可以以这个spider为起点,根据需求修改部分方法。当然你也可以实现自己的spider。
除了从Spider继承过来的属性外,其提供了一个新的属性:
1、rules
一个包含一个(或多个)Rule对象的集合(list)。每个Rule对爬取网站的动作定义了特定表现。Rule对象在下边会介绍。如果多个rule匹配了相同的链接,则根据他们在本属性中被定义的顺序,第一个会被使用。
该spider也提供了一个可复写(overrideable)的方法:
2、parse_start_url(response)
当start_url的请求返回时,该方法被调用。该方法分析最初的返回值并必须返回一个Item对象或者一个Request对象或者一个可迭代的包含二者的对象。

爬取规则(Crawling rules)

class scrapy.contrib.spiders.Rule(link_extractor, callback=None, cb_kwargs=None, follow=None, process_links=None, process_request=None)

  • link_extractor是一个Link Extractor对象。其定义了如何从爬取到的页面提取链接。
  • callback是一个callable或string(该spider中同名的函数将会被调用).从link_extractor中每获取到链接时将会调用该函数。该回调函数接受一个response作为其第一个参数,并返回一个包含Item以及request对象的列表(list)。
    警告
    当编写爬虫规则时,请避免使用parse作为回调函数。由于CrawSpider使用parse方法来实现逻辑,如果你覆盖了这个方法,crawlspider将要失败。
  • cb_kwargs包含传递给回调函数的参数的字典。
  • follow是一个布尔值,指定了根据该规则从response提取的链接是否需要跟进。如果callback为None,follow默认设置为True,否则默认为False。
  • process_links是一个callable或string。从link_extractor中获取到链接列表时将会调用该函数。该方法主要用来过滤。
  • process_request是一个callable或string(该spider中同名的函数将会被调用)。该规则提取到每个request时都会调用该函数。该函数必须返回一个request或者None。(用来过滤request)
    这前面都是解释参数。

    剖析样例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    import scrapy
    from scrapy.contrib.spiders import CrawlSpider, Rule
    from scrapy.contrib.linkextractors import LinkExtractor

    class MySpider(CrawlSpider):
    name = 'example.com'
    allowed_domains = ['example.com']
    start_urls = ['http://www.example.com']

    rules = (
    # 提取匹配 'category.php' (但不匹配 'subsection.php') 的链接并跟进链接(没有callback意味着follow默认为True)
    Rule(LinkExtractor(allow=('category\.php', ), deny=('subsection\.php', ))),

    # 提取匹配 'item.php' 的链接并使用spider的parse_item方法进行分析
    Rule(LinkExtractor(allow=('item\.php', )), callback='parse_item'),
    )

    def parse_item(self, response):
    self.log('Hi, this is an item page! %s' % response.url)

    item = scrapy.Item()
    item['id'] = response.xpath('//td[@id="item_id"]/text()').re(r'ID: (\d+)')
    item['name'] = response.xpath('//td[@id="item_name"]/text()').extract()
    item['description'] = response.xpath('//td[@id="item_description"]/text()').extract()
    return item

首先你要导入scrapy这个包,然后再从这个包里面的什么地方拿出什么东西。
我们从scrapy.contrib.spiders这个位置拿出了CrawlSpider,Rule,从scrapy.contrib.linkextractors拿出了LinkExtractor
接着我们就创建一个继承CrawlSpider的MySpider类。制作CrawlSpider的已经继承了最初的Spider类。所以你这相当于第三次继承。也就是对Spider进行扩展成CrawlSpider,然后你再去扩展。
像name当然是不可缺少的,然后允许的域名allowed_domains,再然后就是start_urls这些基本上都没变。主要是后面的。
后面定义了rules元组(touple),元组里面使用了Rule,当提取了http://www.exanple.com这个主页后就会进行下面的链接提取,如果主页里面有http://www.exanple.com/item.php那么他就会被爬取,并返回response对象给parse_item回调函数。
parse_item回调函数就会针对response对象应用各种解析器进行解析。解析过后染回Item。
该spider将从example.com的首页开始爬取,获取category以及item的链接并对后者使用 parse_item 方法。 当item获得返回(response)时,将使用XPath处理HTML并生成一些数据填入 Item 中。
这就是CrawlSpider。

热评文章