scrapy进阶(CrawlSpider爬虫__爬取整站小说)


重点在于CrawlSpider的学习!!!!!!!!!!!!!


**通过前面的学习我们可以进行一些页面的简单自动话爬取,对于一些比较规则的网站,我们似乎可以用Spider类去应付,可是,对于一些较为复杂或者说链接的存放不规则的网站我们该怎么去爬取呢,接下来的爬虫就是要解决这个问题,而且还可以高度的自动化爬取链接和链接内容**

CrawlSpider类,是建立爬虫的另外一个类。

*(顺便说一下,我们可以继承四种类来建立我们的scrapy爬虫,他们是:Spider类,CrawlSpider类, CSVFeedSpider类和XMLFeedSpider类,今天我们讲的就是CrawlSpider类建立的爬虫)*

CrawlSpider类通过一些规则(rules),使对于链接(网页)的爬取更具有通用性,换句话说,CrawlSpider爬虫为通用性的爬虫,而Spider爬虫更像是为一些特殊网站制定的爬虫。

那我们开始正式的讲解一下CrawlSpider爬虫。。。。


首先我们建立一个爬虫工程:

                      scrapy startproject crawlspider

这个我们很熟悉,接下来创建一个CrawlSpider爬虫

    scrapy genspider -t crawl Crawlspider domain.com

注意上面,我们比Spider爬虫建立时多了一个’-t crawl’,这是值爬虫的类
这样以后我们就可以在我们的spiders文件中找到这个爬虫

import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule


class CrawlspiderSpider(CrawlSpider):
    name = 'crawlspider'
    allowed_domains = ['domain.com']
    start_urls = ['http://domain.com/']

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

    def parse_item(self, response):
        i = {}
        #i['domain_id'] = response.xpath('//input[@id="sid"]/@value').extract()
        #i['name'] = response.xpath('//div[@id="name"]').extract()
        #i['description'] = response.xpath('//div[@id="description"]').extract()
        return i

上面是打开爬虫后,自动生成的一段代码,这段代码可以说基本上对于CrawlSpider爬虫的结构有一个构造,我们看到,有一个rules属性,还有这个爬虫继承的类是CrawlSpider,这两点就是与前几篇讲的Spider爬虫的区别。其中rules属性使这个爬虫的核心

所以我们在开始讲我们的实战项目之前我们应该先讲一下这个rules属性。
rules属性由几个Rule对象构成,而Rule对象定义了提取链接等操作的规则

那么Rule的构造又是怎样的呢?
Rule对象有六个属性,他们分别是:

  1. LinkExtractor(…),用于提取response中的链接
  2. callback=‘str’,回调函数,对提取的链接使用,用于提取数据填充item
  3. cb_kwargs,传递给回调函数的参数字典
  4. follow=True/False,对提取的链接是否需要跟进
  5. process_links,一个过滤链接的函数
  6. process_request,一个过滤链接Request的函数
    上面的参数除了LinkExtractor外其它都是可选的,且当callback参数为None时,我们称这个rule为一个‘跳板’,也就是只下载页面,并不进行任何行为,通常作翻页功能

我们需要解释主要是LinkExtractor参数和follow参数:

一、LinkExtractor参数,明显是用来提取链接的。那么他是怎么来定义提取链接的规则的呢?它有十个参数,用来定义提取链接的规则,分别是:
1. allow=‘re_str’:正则表达式字符串,提取response中符合re表达式的链接。
2. deny=‘re_str’:排除正则表达式匹配的链接
3. restrict_xpaths=‘xpath_str’:提取满足xpath表达式的链接
4. restrict_css=‘css_str’:提取满足css表达式的链接
5. allow_domains=‘domain_str’:允许的域名
6. deny_domains=‘domain_str’:排除的域名
7. tags=‘tag’/[‘tag1’,’tag2’,…]:提取指定标签下的链接,默认会从a和area标签下提取链接
8. attrs=[‘href’,’src’,…]:提取满足属性的链接
9. unique=True/False:链接是否去重
10.process_value:值处理函数,优先级要大于allow
以上的参数可以一起使用,以提取同时满足条件的链接

二、follow参数
为Boolean值,用于是否跟进链接的处理,在callback为None时,默认是跟进链接的,值为True;当callback不为空时,默认是False的,不跟进链接。当然我们可以根据需要赋值

 那么,什么叫跟进,什么叫不跟进呢?
 就是你前面定义的规则对于已经提取到的链接的页面是不是在进行一次提取链接。

好!那么rules到底是怎么工作的呢?
这样的,对于Rule提取的链接会自动调用parse函数,并返回该链接的response,然后将这个response给callback回调函数,通过回调函数的解析对item进行填充

对了,CrawlSpider爬虫还有一个parse_start_url()方法,用于解析start_urls中的链接页面,这个方法一般用于有跳板的爬虫中,用于对首页的解析

说了那么多,我们来说说我们的爬虫项目。用CrawlSpider爬虫,爬取整站的小说

我们的目标网站是:笔趣看小说网
这是一个盗版小说网站,只能在线观看,不能下载。
首页是这样的:
首页
下一部分

整个首页的内容就是上面的样子,那我们的目标就是提取整个首页的所有的小说

首先我们要创建一个CrawlSpider爬虫,创建步骤上面有。
先贴代码,再解释:

# -*- coding: utf-8 -*-
import scrapy,re
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from crawlspider.items import CrawlspiderItem


class CrawlspidersSpider(CrawlSpider):
    name = 'CrawlSpiders'
    allowed_domains = ['sbiquge.com']
    start_urls = ['https://www.sbiquge.com/biqukan/']

    rules = (
        Rule(LinkExtractor(allow="/\d+?_\d+?/",unique=True),callback='parse_item',follow=False),
        # 注意使用restricted_xpath提取链接的时候只能到标签就好了,千万不要到具体的标签属性,那叫画蛇添足。
        # 这个rule实例有callback属性,那么它就是从所有下载到的response里面提取链接,并下载链接内容由回调函数处理数据
    )
    def parse_item(self, response):

        chap_list = response.xpath('.//*[@class="listmain"]/dl/dd')
        for chapter in chap_list:
            novel_name = chapter.xpath('//*[@id="book"]/div[1]/div/a[2]/text()').extract_first()
            chapter_name = chapter.xpath('./a/text()').extract_first()
            chapter_link = chapter.xpath('./a/@href').extract_first()
            if chapter_name:
                item = CrawlspiderItem(chapter_title=chapter_name,novel_name=novel_name)
                url = response.urljoin(chapter_link)
                request = scrapy.Request(url=url,callback=self.parse_body)
                request.meta['key'] = item
                yield request

    def parse_body(self,response):
        item = response.meta['key']
        content_list = response.xpath('.//*[@id="content"]').re('([\u4e00-\u9fa5]|<br>)+?') # 匹配到的是一个列表
        # 利用re直接匹配小说的汉字内容.正则可以匹配标签下的任何内容,这样我们可以提取我们想要的数据
        content_str = ''.join(content_list)
        content = re.sub('<br><br>','\n  ',content_str)
        # 对匹配的章节进行分段
        item['content'] = content
        yield item



上面重点内容都是有注释的,如果有看不懂的地方,看一下我前面几篇文章,就可以了。
这样的经过上面我们填充的item中就有了小说的名字和小说的章节标题及内容了

接下来就是如何将小说存进对应小说文件的,我们可以选择动态的创建文件的方式(不难的)
pipelines.py文件中

class CrawlspiderPipeline(object):
    def process_item(self, item, spider):
        novel = '{}.txt'.format(item['novel_name'])
        # 动态创建小说的文件
        self.file = open(novel, 'a')
        self.file.write(item['chapter_title']+'\n'+item['content'])
        self.file.close()

至于其他几个文件中的代码,和前面几篇的是一样的,有点基础的你应该是不用要的把!
这样的话,我们就可以爬取整个网站的小说了。这是我的成果:
这里写图片描述
这里写图片描述

我只爬取了一点点就停下来了,另外稍微改写一下代码,就爬取到了图一所有小说的名字。
对了,如果你想让程序停下来就Ctrl+C哦!,两次呀。

猜你喜欢

转载自blog.csdn.net/killeri/article/details/80255500