18 scrapy框架中的CrawlSpider详解

CrawlSpider的引入:  

   提问:如果想要通过爬虫程序去爬取”糗百“全站数据新闻数据的话,有几种实现方法?

   方法一:基于Scrapy框架中的Spider的递归爬取进行实现(Request模块递归回调parse方法)。

   方法二:基于CrawlSpider的自动爬取进行实现(更加简洁和高效)

CrawlSpider的简介:

  CrawlSpider其实是Spider的一个子类,除了继承到Spider的特性和功能外,还派生除了其自己独有的更加强大的特性和功能。其中最显著的功能就是”LinkExtractors链接提取器“。Spider是所有爬虫的基类,其设计原则只是为了爬取start_url列表中网页,而从爬取到的网页中提取出的url进行继续的爬取工作使用CrawlSpider更合适。

CrawlSpider的使用:

  CrawlSpider的使用和Spider使用差不多,只有在爬虫文件的时候有所有区别

  1.创建scrapy工程:scrapy startproject projectName

  2.切换到当前的工程目录下  cd projectName

   创建爬虫文件:scrapy genspider -t crawl spiderName www.xxx.com

    --此指令对比以前的指令多了 "-t crawl",表示创建的爬虫文件是基于CrawlSpider这个类的,而不再是Spider这个基类。

   执行爬虫文件 scrapy crawl projectName

  3.观察生成的爬虫文件

     自动生成的爬虫文件 

 1 # -*- coding: utf-8 -*-
 2     import scrapy
 3     from scrapy.linkextractors import LinkExtractor
 4     from scrapy.spiders import CrawlSpider, Rule
 5 
 6     class CsSpider(CrawlSpider):
 7         name = 'cs'
 8         # allowed_domains = ['www.xxx.com']
 9         start_urls = ['http://www.xxx.com/']
10 
11       rules = (
12           Rule(LinkExtractor(allow=r'Items/'), callback='parse_item', follow=True),
13       )
14 
15       def parse_item(self, response):
16           i = {}
17           #i['domain_id'] = response.xpath('//input[@id="sid"]/@value').extract()
18           #i['name'] = response.xpath('//div[@id="name"]').extract()
19           #i['description'] = response.xpath('//div[@id="description"]').extract()
20           return i

通常将爬虫文件更改成下面的形式

 1   # -*- coding: utf-8 -*-
 2   import scrapy
 3   from scrapy.linkextractors import LinkExtractor
 4   # 导入CrawlSpider相关模块
 5   from scrapy.spiders import CrawlSpider, Rule
 6 
 7 
 8   # 表示该爬虫程序是基于CrawlSpider类的
 9   class CsSpider(CrawlSpider):
10       # 爬虫文件名
11       name = 'cs'
12       # allowed_domains = ['www.xxx.com']
13       # 起始的url
14       start_urls = ['http://www.xxx.com/']
15 
16       # 将链接提取器从rules规则解析器中提取出来,
17       # 链接提取器:有一个前提(follow=False),作用就是提取起始url对应页面中符合要求的链接
18       link = LinkExtractor(allow=r'Items/')  #allow后面跟的是一个正则表达式(符合条件要求或规则)
19       # 在rules这个元祖中存放的都是规则解析器
20       # 规则解析器的作用:将链接提取器提取的 链接对应的页面源码数据 根据指定要求进行解析
21      # follow = True: 让链接提取器继续作用在 链接提取器提取出来的 所对应的页面源码中
22       rules = (
23           Rule(link, callback='parse_item', follow=True),
24           # callback指定解析方式
25       )
26 
27       def parse_item(self, response):
28           i = {}
29           #i['domain_id'] = response.xpath('//input[@id="sid"]/@value').extract()
30           #i['name'] = response.xpath('//div[@id="name"]').extract()
31           #i['description'] = response.xpath('//div[@id="description"]').extract()
32           return i

 

CrawlSpider的代码详解:

  1. 导入CrawlSpider相关模块

     from scrapy.linkextractors import LinkExtractor

       from scrapy.spiders import CrawlSpider, Rule

  2.LinkExtractor:顾名思义,链接提取器。

    LinkExtractor(

         allow=r'Items/',# 满足括号中“正则表达式”的值会被提取,如果为空,则全部匹配。

         deny=xxx,  # 满足正则表达式的则不会被提取。

 

         restrict_xpaths=xxx, # 满足xpath表达式的值会被提取

         restrict_css=xxx, # 满足css表达式的值会被提取

         deny_domains=xxx, # 不会被提取的链接的domains。 

        )

    - 作用:提取response中符合规则的链接。

  3.Rule : 规则解析器。根据链接提取器中提取到的链接,根据指定规则提取解析器链接网页中的内容。

     Rule(LinkExtractor(allow=r'Items/'), callback='parse_item', follow=True)

    - 参数介绍:

      参数1:指定链接提取器

      参数2:指定规则解析器解析数据的规则(回调函数)

      参数3:是否将链接提取器继续作用到链接提取器提取出的链接网页中。当callback为None,参数3的默认值为true。

  4. rules=( ):指定不同规则解析器。一个Rule对象表示一种提取规则。

  5. callback指定的是解析方式,默认是parse_item

  6. follow参数

     - follow=False  链接提取器 提取起始url对应页面中符合要求的链接

       - follow = True  让链接提取器继续作用在 链接提取器提取出的来链接 所对应的页面源码中

CrawlSpider整体爬取流程:

   a)爬虫文件首先根据起始url,获取该url的网页内容

   b)链接提取器会根据指定提取规则将步骤a中网页内容中的链接进行提取

   c)规则解析器会根据指定解析规则将链接提取器中提取到的链接中的网页内容根据指定的规则进行解析

   d)将解析数据封装到item中,然后提交给管道进行持久化存储

示例:爬取抽屉新热榜首页中所有的页面  

# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
# 导入CrawlSpider相关模块
from scrapy.spiders import CrawlSpider, Rule


# 表示该爬虫程序是基于CrawlSpider类的
class CsSpider(CrawlSpider):
    # 爬虫文件名
    name = 'cs'
    # allowed_domains = ['www.xxx.com']
    # 起始的url
    start_urls = ['https://dig.chouti.com/all/hot/recent/1']

    # 将链接提取器从rules规则解析器中提取出来,
    # 链接提取器:有一个前提(follow=False),作用就是提取起始url对应页面中符合要求的链接
    link = LinkExtractor(allow=r'/all/hot/recent/\d+')  #allow后面跟的是一个正则表达式(符合条件要求或规则)
    # 在rules这个元祖中存放的都是规则解析器
    # 规则解析器的作用:将链接提取器提取的 链接对应的页面源码数据 根据指定要求进行解析
    # follow=True:让链接提取器继续作用在 链接提取器提取出的来链接 所对应的页面源码中
    rules = (
        Rule(link, callback='parse_item', follow=False),
        # callback指定解析方式
    )

    def parse_item(self, response):
        print(response)
        # response对应的是对拿到的每一个链接发请求拿到的响应对象

一个特殊的情况: 

示例:爬取糗事百科糗图板块的所有页码数据

 1 # 表示该爬虫程序是基于CrawlSpider类的
 2   class CsSpider(CrawlSpider):
 3       # 爬虫文件名
 4       name = 'cs'
 5       # allowed_domains = ['www.xxx.com']
 6       # 起始的url
 7      start_urls = ['https://www.qiushibaike.com/pic/']
 8 
 9       # 将链接提取器从rules规则解析器中提取出来,
10       # 链接提取器:有一个前提(follow=False),作用就是提取起始url对应页面中符合要求的链接
11       link = LinkExtractor(allow=r'/pic/page/\d+\?') #s=为随机数
12       link1 = LinkExtractor(allow=r'/pic/$') #s=为随机数
13       # 在rules这个元祖中存放的都是规则解析器
14       # 规则解析器的作用:将链接提取器提取的 链接对应的页面源码数据 根据指定要求进行解析
15       # follow=True:让链接提取器继续作用在 链接提取器提取出的来链接 所对应的页面源码中
16       rules = (
17           Rule(link, callback='parse_item', follow=False),
18           Rule(link1, callback='parse_item', follow=True),
19           # callback指定解析方式
20       )
21       def parse_item(self, response):
22           print(response)
23           # response对应的是对拿到的每一个链接发请求拿到的响应对象

 

posted on 2019-03-15 09:36  盛夏中为你花开彼岸  阅读(183)  评论(0编辑  收藏  举报

导航