scrapy_redis原理分析並實現斷點續爬以及分佈式爬蟲

學習目標
  1. 瞭解 scrapy實現去重的原理
  2. 瞭解 scrapy中請求入隊的條件
  3. 掌握 scrapy_redis基於url地址的增量式單機爬蟲
  4. 掌握 scrapy_redis分佈式爬蟲

1. 下載github的demo代碼

  1. clone github scrapy-redis源碼文件css

    git clone https://github.com/rolando/scrapy-redis.gitgit

  2. 研究項目自帶的demogithub

    mv scrapy-redis/example-project ~/scrapyredis-projectredis

2. 觀察dmoz文件

在domz爬蟲文件中,實現方式就是以前的crawlspider類型的爬蟲bash

from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule


class DmozSpider(CrawlSpider):
    """Follow categories and extract links."""
    name = 'dmoz'
    allowed_domains = ['dmoztools.net']
    start_urls = ['http://dmoztools.net/'] # 這裏修改了url
    
    # 定義數據提取規則,使用了css選擇器
    rules = [
        Rule(LinkExtractor(
            restrict_css=('.top-cat', '.sub-cat', '.cat-item')
        ), callback='parse_directory', follow=True),
    ]

    def parse_directory(self, response):
        for div in response.css('.title-and-desc'):
            yield {
                'name': div.css('.site-title::text').extract_first(),
                'description': div.css('.site-descr::text').extract_first().strip(),
                'link': div.css('a::attr(href)').extract_first(),
            }

複製代碼

可是在settings.py中多瞭如下內容,這幾行表示scrapy_redis中從新實現的了去重的類,以及調度器,而且使用RedisPipeline管道類框架

DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
SCHEDULER_PERSIST = True

ITEM_PIPELINES = {
    'example.pipelines.ExamplePipeline': 300,
    'scrapy_redis.pipelines.RedisPipeline': 400,
}
複製代碼

3. 運行dmoz爬蟲,觀察現象

  1. 首先咱們須要添加redis的地址,程序纔可以使用redis
REDIS_URL = "redis://127.0.0.1:6379"
#或者使用下面的方式
# REDIS_HOST = "127.0.0.1"
# REDIS_PORT = 6379
複製代碼
  1. 咱們執行domz的爬蟲,會發現redis中多了一下三個鍵:

  1. 停止進程後再次運行dmoz爬蟲

繼續執行程序,會發現程序在前一次的基礎之上繼續日後執行,因此domz爬蟲是一個基於url地址的增量式的爬蟲dom

4. scrapy_redis的原理分析

咱們從settings.py中的三個配置來進行分析 分別是:scrapy

  • RedisPipeline # 管道類
  • RFPDupeFilter # 指紋去重類
  • Scheduler # 調度器類
  • SCHEDULER_PERSIST # 是否持久化請求隊列和指紋集合

4.1 Scrapy_redis之RedisPipeline

RedisPipeline中觀察process_item,進行數據的保存,存入了redis中分佈式

4.2 Scrapy_redis之RFPDupeFilter

RFPDupeFilter 實現了對request對象的加密ide

4.3 Scrapy_redis之Scheduler

scrapy_redis調度器的實現了決定何時把request對象加入帶抓取的隊列,同時把請求過的request對象過濾掉

4.4 由此能夠總結出request對象入隊的條件

  • request的指紋不在集合中
  • request的dont_filter爲True,即不過濾
    • start_urls中的url地址會入隊,由於他們默認是不過濾

4.5 實現單機斷點續爬

改寫網易招聘爬蟲,該爬蟲就是一個經典的基於url地址的增量式爬蟲

5. 實現分佈式爬蟲

5.1 分析demo中代碼

打開example-project項目中的myspider_redis.py文件

經過觀察代碼:

  1. 繼承自父類爲RedisSpider
  2. 增長了一個redis_key的鍵,沒有start_urls,由於分佈式中,若是每臺電腦都請求一次start_url就會重複
  3. 多了__init__方法,該方法不是必須的,能夠手動指定allow_domains
  4. 啓動方法:
    1. 在每一個節點正確的目錄下執行scrapy crawl 爬蟲名,使該節點的scrapy_redis爬蟲程序就位
    2. 在共用的redis中 lpush redis_key 'start_url',使所有節點真正的開始運行
  5. settings.py中關鍵的配置
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
SCHEDULER_PERSIST = True

ITEM_PIPELINES = {
    'example.pipelines.ExamplePipeline': 300,
    'scrapy_redis.pipelines.RedisPipeline': 400,
}
REDIS_URL = "redis://127.0.0.1:6379"
複製代碼

5.2 動手實現分佈式爬蟲

改寫tencent爬蟲爲分佈式爬蟲

注意:啓動方式發生改變

小結

  1. scrapy_redis的含義和可以實現的功能

    1. scrapy是框架
    2. scrapy_redis是scrapy的組件
    3. scrapy_redis可以實現斷點續爬和分佈式爬蟲
  2. scrapy_redis流程和實現原理

    1. 在scrapy框架流程的基礎上,把存儲request對象放到了redis的有序集合中,利用該有序集合實現了請求隊列
    2. 並對request對象生成指紋對象,也存儲到同一redis的集合中,利用request指紋避免發送重複的請求
  3. request對象進入隊列的條件

    1. request的指紋不在集合中
    2. request的dont_filter爲True,即不過濾
  4. request指紋的實現

    • 請求方法
    • 排序後的請求地址
    • 排序並處理過的請求體或空字符串
    • 用hashlib.sha1()對以上內容進行加密
  5. scarpy_redis實現增量式爬蟲、布式爬蟲

    1. 對setting進行以下設置
      • DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
      • SCHEDULER = "scrapy_redis.scheduler.Scheduler"
      • SCHEDULER_PERSIST = True
      • ITEM_PIPELINES = {'scrapy_redis.pipelines.RedisPipeline': 400,}
      • REDIS_URL = "redis://127.0.0.1:6379" # 請正確配置REDIS_URL
    2. 爬蟲文件中的爬蟲類繼承RedisSpider類
    3. 爬蟲類中redis_key替代了start_urls
    4. 啓動方式不一樣
      • 經過scrapy crawl spider啓動爬蟲後,向redis_key放入一個或多個起始url(lpush或rpush均可以),纔可以讓scrapy_redis爬蟲運行
    5. 除了以上差別點之外,scrapy_redis爬蟲和scrapy爬蟲的使用方法都是同樣的
相關文章
相關標籤/搜索