python ------scrapy-redis分布式爬虫

一,scrapy和scrapy-redis的区别?

    scrapy是一个爬虫通用框架,但不支持分布式,scrapy-redis是为了更方便的实现scrapy分布式爬虫,而提供了一些以redis为基础的组件

二,为什么scrapy框架不支持分布式?

    因为scrcapy中的调度对列不支持共享,而scrapy-redis中,可以共享该对列

三,scrapy-redis工作原理?

        1,爬虫程序把请求链接,发送给爬虫引擎,

        2,爬虫引擎把请求链接传递到调度对列

        3,调度sheduler会把链接存放到redis数据库中

        4,redis数据库因为具有集合的性质,对去重有更好的体现,传进来的链接会生成一个指纹,   redis会把 传进来的链接进行对比,相同的链接直接去重,把没有的链接加入到对列中,然后把链接再传递到调度对列中。

        5,调度中的对列把链接发送到下载模块

        6,下载模块,下载好数据后,把数据及下载的链接发送到爬虫程序

        7,爬虫程序把数据及链接发送到redis数据库(如果此时自定义管道,则会把数据存放到自定义的数据库中)

        8.,可以从redis数据库中把数据下载到本地

四,redis怎么去重的?

如果多台机器不仅往请求队列存,还同时从里面取,那么如何保证每台机子请求和存储的队列是不重复的呢?

借助redis集合

redis提供集合数据结构,我们知道集合里面的元素是不重复的

首先,在redis中存储每个request的指纹。

在向request队列中加入request前首先验证这个request的指纹是否已经加入到集合中。

如果已存在,则不添加requets到队列,

如果不存在,则将request添加入队列并将指纹加入集合。

五,分布式爬虫架构实际上就是:

由一台主机维护所有的爬取队列,每台从机的sheduler共享该队列,协同存储与提取。

分布式爬虫的多台协作的关键是共享爬取队列

六,队列用什么维护呢?

推荐redis队列

redis是非关系型数据库,用key-value形式存储,结构灵活,他不像关系型数据库必须要由一定的结构才能存储。

key-value可以是多种数据,非常灵活。

另外,redis是内存中的数据结构存储系统,处理速度快,性能好。

提供了队列,集合多种存储结构,方便队列维护和去重操作。

七,怎样防止中断?

在爬取的过程中,难免会有某台机子卡掉了,这时怎么办?

在每台从机scrapy启动时都会首先判断当前redis request队列是否为空。

如果不为空,则从队列中取得下一个request执行爬取。

如果为空,则重新开始开始爬取,第一台从机执行爬取想队列中添加request。

怎样实现该架构?

要做到:

维护request队列

对台从机调度reuqest

设置去重

链接redis

已经有了比较成熟的库scrapy-redis

scrapy-redis库实现了如上架构,改写了scrapy的调度器,队列等组件

利用它可以方便地实现scrapy分布式架构

https://github.com/rolando/scrapy-redis

八,步骤及代码

        1,安装redis

            启动redis服务:redis-server

            启用shell客户端:redis-cli 可以输入指令 (在这里面启动指令)

        2,修改配置文件redis.conf

        把bind:127.0.0.1注释掉,可以让其他IP也可以访问,其他爬虫端才能连接到服务端的数据库

        3,连接到服务端测试

        linux下  sudo redis-cli -h 服务端的IP  -h指定

        如果-h没有指定,就会默认在本地

        slave端无需启动radis-server,mster端启动即可,只要slave能读取到mster中的数据库就行了

        代表可以实施分布式

        4,自动构建一个scrapy框架 scrapy startproject 项目名(做修改)

        5,关于settings中代码的修改

             DOWNLOAD_DELAY =0.5 #下载延迟,就是从别人服务器上获取数据时,延迟时间    

            SCHEDULER ="scrapy_redis.scheduler.Scheduler"     #任务调度,使用scrapy-redis里面的调度器组件,不使用scrapy默认的调度器

            DUPEFILTER_CLASS ="scrapy_redis.dupefilter.RFPDupeFilter"      #去重,用的是scrapy_redis里的去重组件,不适用scrapy默认的去重

SCHEDULER_PERSIST =True   #是否开启,允许暂停,redis请求记录不丢失

SCHEDULER_QUEUE_CLASS ='scrapy_redis.queue.SpiderQueue'      #调度策略:队列,默认是scrapy_redis请求,(按优先级顺序)队列形成   (有三种形式,只是一个先后顺序,影响不大)

#指定redis数据库的主机

REDIS_HOST ='127.0.0.1' #修改为Redis的实际IP地址

REDIS_PORT =6379 #修改为Redis的实际端口

    6,爬虫程序的开发

导入需要的模块

# -*- coding: utf-8 -*-

import scrapy

from scrapy_redis.spidersimport RedisCrawlSpider

from scrapy.spidersimport CrawlSpider, Rule

from scrapy.linkextractorsimport LinkExtractor

from ..itemsimport  ScrapyRedisExampleItem

继承类也是需要改变的:

class CountrySpider(RedisCrawlSpider):

   name ='country'

    redis_key ='start_urls'  #指令,用来启动爬虫端程序的

    7,开多个运行窗口进行采集,模拟分布式,在服务端输入指令

搭建分布式最合适:对硬件的要求,在不同网段里面,各自处理各自的请求,这样才能体会到分布式的精髓


        

你可能感兴趣的:(python ------scrapy-redis分布式爬虫)