scrapy的组建scrapy Engine ,scheduler,downloader,spider,item pipeline ,在编写爬虫程序一般用到的组件是 spider,item,pipeline,middleware

scrapy-redis 改写了scrapy的spider,pipeline,shedulers组件,由于scrapy原本的sheduler是在内存中,不支持分布式。

scrapy-redis改写了 spider中下载得到的request和item的传递路径,由传给原本的sheduler变更为 传给 共用的redis,在redis中存储并去重得到的request,最终得到的items也存储在redis中,sheduler由scrapy-redis内部实现。

这些改写,使得在编写分布式爬虫程序时,spider.py中由原来的继承scrapy.spiders.Spider变为继承scrapy_redis.spiders.RedisSpider,其他的无变化

item.py中无变化,Pipeline.py中也无变换,middlerwares.py中也无变化

主要设置在settings.py中

#scrapy-redis定义的Scheduler
SCHEDULER = 'scrapy_redis.scheduler.Scheduler'
#利用redis去重:
DUPEFILTER_CLASS = 'scrapy_redis.dupefilter.RFPDupeFilter'
#序列化方案
SCHEDULER_SERIALIZER = 'scrapy_redis.picklecompat'
#当scrapy中断时,是否保存记录,以便下次开启时能接着爬取
SCHEDULER_PERSIST = True

#是否在开启爬虫时清空上次留下的记录(去重,待爬url)

#SCHEDULER_FLUSH_ON_START=False

#队列名
REDIS_ITEMS_KEY='%(spider)s:items'

#键值对中键值命名规则
REDIS_START_URLS_KEY='%(name)s:start_urls'

#去重key值

#SCHEDULER_DUPEFILTER_KEY='%(spider)s:dupefilter'

#设置set格式(不允许重复的元素)
REDIS_START_URLS_AS_SET=False 

#redis用于连接的参数redis.StrictRedis()
REDIS_PARAMS={
'host' : '120.79.135.4',
'port' : 6379,
'db' : 0,
'password' : 'redis$yeah',
'encoding':'utf-8',
}
scrapy-redis中主管redis连接的内容在 connection.py中,dupefilter.py用于去重,queue.py和scheduler.py实现了调度

上面的设置都是由于更换的scheduler到redis中所以需要添加的redis配置,下面的pipeline的设置需要注意的是scrapy_redis.pipelines.RedisPipeline是最后处理item的管道,所以如果要将item做其他的加工存储,写的pipeline的优先度排在它之前就可
#item存储管道
ITEM_PIPELINES={
'scrapy_redis.pipelines.RedisPipeline':300,
'myspider.pipelines.Tongch58Pipelines.PgPipeline':290,}

对scrapy项目进行了上述改动后,就可以将项目clone到不同的server上,进入项目所在的目录,执行 scrapy crawl spidername   就开启了各服务器上的spider,这时向共用的redis中执行 lpush myspider:start_urls https://myfisrt_crawl_url.com      各服务器上的spider之一就会爬去首页之一,将爬到的url存储到redis的 myspider:requests列表中存储,各sipder又从myspider:requests中获取url来爬取。

原scrapy中对requests的去重是在scheduler,所以,scrapy-redis重写的scheduler,利用了redis的set的特性实现了去重,在运行的过程中,在redis中看到这几个键值:

myspider:dupefilter   用于存储去重后的request

myspider:items          用于存储最终的items 

myspider:requests     用于存储待爬去的request

scheduler在每个主机上都会实例化一个,并且和spider一一对应,所以分布式运行时会有一个spider的多个实例和一个scheduler的多个实例存在于不同的主机上,但是,因为scheduler都是用相同的调度机制,而这些容器都连接同一个redis服务器,又都使用spider名加queue来作为key读写数据,所以不同主机上的不同爬虫实例公用一个request池,实现了分布式爬虫之间的统一调度。 

 

github上对scrapy-redis的介绍 https://github.com/rmax/scrapy-redis

 posted on 2018-10-19 15:22  庭明  阅读(210)  评论(0编辑  收藏  举报