6 scrapy框架之分布式操作
分布式爬蟲
一.redis簡單回顧
1.啟動redis:
mac/linux:?? redis-server redis.conf
windows: redis-server.exe redis-windows.conf
2.對redis配置文件進行配置:
- 注釋該行:bind 127.0.0.1,表示可以讓其他ip訪問redis
- 將yes該為no:protected-mode no,表示可以讓其他ip操作redis
二.scrapy基于redis的數據持久化操作流程
1.安裝scrapy-redis組件:
- pip install scrapy-redis
- scrapy-redis是基于scrapy框架開發出的一套組件,其作用就是可以讓scrapy實現分布式爬蟲。
2.編寫爬蟲文件:
- 同之前scrapy中基于Spider或者CrawlSpider的編寫方式一致。
3.編寫管道文件:
- 在scrapy-redis組件中已經幫助我們封裝好了一個專門用于連接存儲redis數據庫的管道(RedisPipeline),因此我們直接使用即可,無需自己編寫管道文件。
4.編寫配置文件:
- 在settings.py中開啟管道,且指定使用scrapy-redis中封裝好的管道。
ITEM_PIPELINES = {'scrapy_redis.pipelines.RedisPipeline': 400 }- 該管道默認會連接且將數據存儲到本機的redis服務中,如果想要連接存儲到其他redis服務中需要在settings.py中進行如下配置:
REDIS_HOST = 'redis服務的ip地址' REDIS_PORT = 6379 REDIS_ENCODING = ‘utf-8’ REDIS_PARAMS = {‘password’:’123456’}三.redis分布式部署
1.scrapy框架是否可以自己實現分布式?
- 不可以。原因有二。
其一:因為多臺機器上部署的scrapy會各自擁有各自的調度器,這樣就使得多臺機器無法分配start_urls列表中的url。(多臺機器無法共享同一個調度器)
其二:多臺機器爬取到的數據無法通過同一個管道對數據進行統一的數據持久出存儲。(多臺機器無法共享同一個管道)
2.redis實現分布式基本流程:
- 使用基于scrapy-redis組件中的爬蟲文件。
import scrapy from scrapy.linkextractors import LinkExtractor from scrapy.spiders import CrawlSpider, Rule from movieproject.items import MovieprojectItem #導入scrapy-redis中的模塊 from scrapy_redis.spiders import RedisCrawlSpiderclass NnSpider(RedisCrawlSpider):name = 'nn'allowed_domains = ['www.id97.com']#redis_key表示調度器中的隊列(將要爬取的頁面數據對應的url都需要放置到調度器隊列中)redis_key = 'nnspider:start_urls'# 根據規則提取所有的頁碼鏈接page_link = LinkExtractor(allow=r'/movie/\?page=\d')detail_link = LinkExtractor(restrict_xpaths='//div[contains(@class,"col-xs-1-5")]/div/a')# detail_link = LinkExtractor(allow=r'/movie/\d+\.html$')# follow : 是否跟進rules = (# 所有的頁碼不用處理,跟進即可Rule(page_link, follow=True),# 所有的詳情頁處理,不用跟進Rule(detail_link, callback='parse_item', follow=False),)def parse_item(self, response):# 創建一個item對象item = MovieprojectItem()# 電影海報item['post'] = response.xpath('//a[@class="movie-post"]/img/@src').extract_first()# 電影名字item['name'] = response.xpath('//h1').xpath('string(.)').extract_first()yield item viewfrom scrapy.linkextractors import LinkExtractor from scrapy.spiders import CrawlSpider, Rule from redisPro.items import RedisproItemfrom scrapy_redis.spiders import RedisCrawlSpiderclass QiubaiSpider(RedisCrawlSpider):name = 'qiubai'#allowed_domains = ['https://www.qiushibaike.com/pic/']#start_urls = ['https://www.qiushibaike.com/pic/']#調度器隊列的名稱redis_key = 'qiubaispider' #表示跟start_urls含義是一樣,redis數據庫里面的值link = LinkExtractor(allow=r'/pic/page/\d+')rules = (Rule(link, callback='parse_item', follow=True),)def parse_item(self, response):div_list = response.xpath('//div[@id="content-left"]/div')for div in div_list:img_url = "https:"+div.xpath('.//div[@class="thumb"]/a/img/@src').extract_first()item = RedisproItem()item['img_url'] = img_urlyield item- 使用scrapy-redis組件中封裝好的調度器,將所有的url存儲到該指定的調度器中,從而實現了多臺機器的調度器共享。
# 使用scrapy-redis組件的去重隊列 DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter" # 使用scrapy-redis組件自己的調度器 SCHEDULER = "scrapy_redis.scheduler.Scheduler" # 是否允許暫停 SCHEDULER_PERSIST = True- 使用scrapy-redis組件中封裝好的管道,將每臺機器爬取到的數據存儲通過該管道存儲到redis數據庫中,從而實現了多臺機器的管道共享。
ITEM_PIPELINES = {'scrapy_redis.pipelines.RedisPipeline': 400, }- 執行:scrapy runspider xxx.py,然后向調度器隊列中傳入起始url:lpush nnspider:start_urls http://www.xxx.com/
總結
以上是生活随笔為你收集整理的6 scrapy框架之分布式操作的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 5 CrawlSpider操作
- 下一篇: Docker 网络基础原理