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定义的SchedulerSCHEDULER = '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
转载于:https://www.cnblogs.com/Ting-light/p/9816638.html
相关资源:Python分布式爬虫打造搜索引擎