問題:
- 為什麼原生的scrapy不能實現分散式?
- 排程器不能被共享
- 管道無法被共享
- scrapy-redis元件的作用是什麼?
- 提供了可以被共享的排程器和管道
實現分散式爬蟲的流程?
1.環境安裝:pip install scrapy-redis 2.建立工程 3.建立爬蟲檔案:RedisCrawlSpider RedisSpider - scrapy genspider -t crawl xxx www.xxx.com 4.對爬蟲檔案中的相關屬性進行修改: - 導報:from scrapy_redis.spiders import RedisCrawlSpider - 將當前爬蟲檔案的父類設定成RedisCrawlSpider - 將起始url列表替換成redis_key = 'xxx'(排程器佇列的名稱) 5.在配置檔案中進行配置: - 使用元件中封裝好的可以被共享的管道類: ITEM_PIPELINES = { 'scrapy_redis.pipelines.RedisPipeline': 400 } - 配置排程器(使用元件中封裝好的可以被共享的排程器) # 增加了一個去重容器類的配置, 作用使用Redis的set集合來儲存請求的指紋資料, 從而實現請求去重的持久化 DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter" # 使用scrapy-redis元件自己的排程器 SCHEDULER = "scrapy_redis.scheduler.Scheduler" # 配置排程器是否要持久化, 也就是當爬蟲結束了, 要不要清空Redis中請求佇列和去重指紋的set。如果是True, 就表示要持久化儲存, 就不清空資料, 否則清空資料 SCHEDULER_PERSIST = True - 指定儲存資料的redis: REDIS_HOST = 'redis服務的ip地址' REDIS_PORT = 6379 - 配置redis資料庫的配置檔案 - 取消保護模式:protected-mode no - bind繫結: #bind 127.0.0.1 - 啟動redis 6.執行分散式程式 scrapy runspider xxx.py 7.向排程器佇列中仍入一個起始url: 在redis-cli中執行:
【需求】爬取抽屜網中的標題和作者
程式碼部分:
chouti.py:
# -*- coding: utf-8 -*- import scrapy from scrapy.linkextractors import LinkExtractor from scrapy.spiders import CrawlSpider, Rule from scrapy_redis.spiders import RedisCrawlSpider from redisChoutiPro.items import RedischoutiproItem class ChoutiSpider(RedisCrawlSpider): name = 'chouti' # allowed_domains = ['www.xxx.com'] # start_urls = ['http://www.xxx.com/'] redis_key = 'chouti' rules = ( Rule(LinkExtractor(allow=r'/all/hot/recent/\d+'), callback='parse_item', follow=True), ) def parse_item(self, response): div_list = response.xpath('//div[@class = "item"]') for div in div_list: title = div.xpath('./div[4]/div[1]/a/text()').extract_first() author = div.xpath('./div[4]/div[2]/a[4]/b/text()').extract_first() item = RedischoutiproItem() item['title'] = title item['author'] = author yield item
items.py
import scrapy class RedischoutiproItem(scrapy.Item): # define the fields for your item here like: title = scrapy.Field() author = scrapy.Field()
settings.py
ITEM_PIPELINES = { 'scrapy_redis.pipelines.RedisPipeline': 400 } # 增加了一個去重容器類的配置, 作用使用Redis的set集合來儲存請求的指紋資料, 從而實現請求去重的持久化 DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter" # 使用scrapy-redis元件自己的排程器 SCHEDULER = "scrapy_redis.scheduler.Scheduler" # 配置排程器是否要持久化, 也就是當爬蟲結束了, 要不要清空Redis中請求佇列和去重指紋的set。如果是True, 就表示要持久化儲存, 就不清空資料, 否則清空資料 SCHEDULER_PERSIST = True #資料指紋 REDIS_HOST = '127.0.0.1' REDIS_PORT = 6379