Scrapy爬取规则(Crawling rules)如何应用

Scrapy官网上对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对象。 其定义了如何从爬取到的页面提取链接。

  • follow是一个布尔(boolean)值,指定了根据该规则从response提取的链接是否需要跟进。 如果callback 为None,follow 默认设置为True,否则默认为False。

然后还有一段重要的警告:

当编写爬虫规则时,请避免使用parse作为回调函数。 由于CrawlSpider使用parse方法来实现其逻辑,如果您覆盖了parse方法,crawl spider 将会运行失败。

官网上给出的配合rule使用CrawlSpider的例子:

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

初看这段代码及说明,心里有这样几个疑问:
1、没有parse()方法(及start_requests()方法),爬虫的入口方法是哪个?
2、Rule(LinkExtractor(allow=('category\.php', ), deny=('subsection\.php', ))),没有callback 这里定义的Rule是哪个方法来处理?
3、示例代码中,爬虫新的url在哪里添加?
4、rules好像只要作定义就可以,不需要在配置文件里再进行配置。

对比之前Scrapy中写过的代码,处理的流程是,1)定义好爬虫的入口(包括start_urls),2)做好爬取过程中url的添加,(通常是列表页和分页),3)内容页字段的提取。现在使用了Rules,以上的步骤不一样了,但是这几步骤是如何实现的,需要探究一番。

我没有从源码中去深入了解,想通过代码的方式来快速测试,了解一下rules的一些使用方法。

实验:

  1. 定义爬虫的起始url 为 简书首页。start_urls=['http://www.jianshu.com']

  2. 爬取rules定为简书的用户主页(/users/xxxx)和文章页(/p/xxxx)

        rules = [
        Rule(SgmlLinkExtractor(allow=(r'http://www.jianshu.com/users/[a-z0-9]+?'))),
        Rule(SgmlLinkExtractor(allow=(r'http://www.jianshu.com/p/[a-z0-9]+?')), callback="parse_item"),

测试结果:
1、定义好rules后,Spider会自动管理url
2、以简书爬取为例,能自动管理的url包括文章页(articles),粉丝页(followers),最新动态页(timeline)… 还包含所有的分页。

《Scrapy爬取规则(Crawling rules)如何应用》 控制台url信息
《Scrapy爬取规则(Crawling rules)如何应用》 控制台url信息

结论和疑问:
1、rules很适合做全站内容的爬取。
2、要提取指定页面数据,rules要定义更准确些。(正则表达式)
3、定义rules之后如何做登录,还不太清楚。
重写start_requests()方法后,不清楚再如何调才能使用rules在爬虫中运转起来。是不适合有登录的爬取吗?
4、follow用法不太清楚。没有callback的rule是哪个方法在处理?

点赞