網絡爬蟲之第六章Scrapy-Redis分佈式組件

第一節:redis數據庫介紹

概述

redis是一種支持分佈式的nosql數據庫,他的數據是保存在內存中,同時redis能夠定時把內存數據同步到磁盤,便可以將數據持久化,而且他比memcached支持更多的數據結構(string,list列表[隊列和棧],set[集合],sorted set[有序集合],hash(hash表))。相關參考文檔:http://redisdoc.com/index.htmlphp

redis使用場景:

  1. 登陸會話存儲:存儲在redis中,與memcached相比,數據不會丟失。
  2. 排行版/計數器:好比一些秀場類的項目,常常會有一些前多少名的主播排名。還有一些文章閱讀量的技術,或者新浪微博的點贊數等。
  3. 做爲消息隊列:好比celery就是使用redis做爲中間人。
  4. 當前在線人數:仍是以前的秀場例子,會顯示當前系統有多少在線人數。
  5. 一些經常使用的數據緩存:好比咱們的BBS論壇,板塊不會常常變化的,可是每次訪問首頁都要從mysql中獲取,能夠在redis中緩存起來,不用每次請求數據庫。
  6. 把前200篇文章緩存或者評論緩存:通常用戶瀏覽網站,只會瀏覽前面一部分文章或者評論,那麼能夠把前面200篇文章和對應的評論緩存起來。用戶訪問超過的,就訪問數據庫,而且之後文章超過200篇,則把以前的文章刪除。
  7. 好友關係:微博的好友關係使用redis實現。
  8. 發佈和訂閱功能:能夠用來作聊天軟件。

redismemcached的比較:

  memcached redis
類型 純內存數據庫 內存磁盤同步數據庫
數據類型 在定義value時就要固定數據類型 不須要
虛擬內存 不支持 支持
過時策略 支持 支持
存儲數據安全 不支持 能夠將數據同步到dump.db中
災難恢復 不支持 能夠將磁盤中的數據恢復到內存中
分佈式 支持 主從同步
訂閱與發佈 不支持 支持

redisubuntu系統中的安裝與啓動

  1. 安裝:
    sudo apt-get install redis-server
  2. 卸載:
    sudo apt-get purge --auto-remove redis-server
  3. 啓動:redis安裝後,默認會自動啓動,能夠經過如下命令查看:html

    ps aux|grep redis

    若是想本身手動啓動,能夠經過如下命令進行啓動:python

    sudo service redis-server start
  4. 中止:mysql

    sudo service redis-server stop

redis在windows系統中的安裝與啓動:

  1. 下載:redis官方是不支持windows操做系統的。可是微軟的開源部門將redis移植到了windows上。所以下載地址不是在redis官網上。而是在github上:https://github.com/MicrosoftArchive/redis/releases。
  2. 安裝:點擊一頓下一步安裝就能夠了。
  3. 運行:進入到redis安裝所在的路徑而後執行redis-server.exe redis.windows.conf就能夠運行了。
  4. 鏈接:redismysql以及mongo是同樣的,都提供了一個客戶端進行鏈接。輸入命令redis-cli(前提是redis安裝路徑已經加入到環境變量中了)就能夠鏈接到redis服務器了。

其餘機器訪問本機redis服務器:

想要讓其餘機器訪問本機的redis服務器。那麼要修改redis.conf的配置文件,將bind改爲bind [本身的ip地址或者0.0.0.0],其餘機器才能訪問。
注意:bind綁定的是本機網卡的ip地址,而不是想讓其餘機器鏈接的ip地址。若是有多塊網卡,那麼能夠綁定多個網卡的ip地址。若是綁定到額是0.0.0.0,那麼意味着其餘機器能夠經過本機全部的ip地址進行訪問。
git

redis的操做

redis的操做能夠用兩種方式,第一種方式採用redis-cli,第二種方式採用編程語言,好比PythonPHPJAVA等。 github

  1. 使用redis-cliredis進行字符串操做:web

  2. 啓動redisredis

    sudo service redis-server start
  3. 鏈接上redis-server
    redis-cli -h [ip] -p [端口]
  4. 添加:sql

    set key value 如: set username xiaotuo

    將字符串值value關聯到key。若是key已經持有其餘值,set命令就覆寫舊值,無視其類型。而且默認的過時時間是永久,即永遠不會過時。數據庫

  5. 刪除:

    del key 如: del username
  6. 設置過時時間:

    expire key timeout(單位爲秒)

    也能夠在設置值的時候,一同指定過時時間:

    set key value EX timeout 或: setex key timeout value
  7. 查看過時時間:

    ttl key 如: ttl username
  8. 查看當前redis中的全部key

    keys *
  9. 列表操做:

    • 在列表左邊添加元素:

      lpush key value

      將值value插入到列表key的表頭。若是key不存在,一個空列表會被建立並執行lpush操做。當key存在但不是列表類型時,將返回一個錯誤。

    • 在列表右邊添加元素:

      rpush key value

      將值value插入到列表key的表尾。若是key不存在,一個空列表會被建立並執行RPUSH操做。當key存在但不是列表類型時,返回一個錯誤。

    • 查看列表中的元素:

      lrange key start stop

      返回列表key中指定區間內的元素,區間以偏移量startstop指定,若是要左邊的第一個到最後的一個lrange key 0 -1

    • 移除列表中的元素:

      • 移除並返回列表key的頭元素:
        lpop key
      • 移除並返回列表的尾元素:
        rpop key
      • 移除並返回列表key的中間元素:

        lrem key count value

        將刪除key這個列表中,count個值爲value的元素。

    • 指定返回第幾個元素:

      lindex key index

      將返回key這個列表中,索引爲index的這個元素。

    • 獲取列表中的元素個數:

      llen key 如: llen languages
    • 刪除指定的元素:

      lrem key count value
        如:
        lrem languages 0 php

      根據參數 count 的值,移除列表中與參數 value 相等的元素。count的值能夠是如下幾種:

      • count > 0:從表頭開始向表尾搜索,移除與value相等的元素,數量爲count
      • count < 0:從表尾開始向表頭搜索,移除與 value相等的元素,數量爲count的絕對值。
      • count = 0:移除表中全部與value 相等的值。
  10. set集合的操做:

    • 添加元素:
      sadd set value1 value2....
        如:
        sadd team xiaotuo datuo
    • 查看元素:
      smembers set
        如:
        smembers team
    • 移除元素:
      srem set member...
        如:
        srem team xiaotuo datuo
    • 查看集合中的元素個數:
      scard set
        如:
        scard team1
    • 獲取多個集合的交集:
      sinter set1 set2
        如:
        sinter team1 team2
    • 獲取多個集合的並集:
      sunion set1 set2
        如:
        sunion team1 team2
    • 獲取多個集合的差集:
      sdiff set1 set2
      如:
      sdiff team1 team2
  11. hash哈希操做:

    • 添加一個新值:

      hset key field value
        如:
        hset website baidu baidu.com

      將哈希表key中的域field的值設爲value
      若是key不存在,一個新的哈希表被建立並進行 HSET操做。若是域 field已經存在於哈希表中,舊值將被覆蓋。

    • 獲取哈希中的field對應的值:

      hget key field
        如:
        hget website baidu
    • 刪除field中的某個field

      hdel key field
        如:
        hdel website baidu
    • 獲取某個哈希中全部的fieldvalue

      hgetall key
        如:
        hgetall website
    • 獲取某個哈希中全部的field

      hkeys key
        如:
        hkeys website
    • 獲取某個哈希中全部的值:

      hvals key
      如:
      hvals website
    • 判斷哈希中是否存在某個field

      hexists key field
      如:
      hexists website baidu
    • 獲取哈希中總共的鍵值對:

      hlen field
      如:
      hlen website
  12. 事務操做:Redis事務能夠一次執行多個命令,事務具備如下特徵:

    • 隔離操做:事務中的全部命令都會序列化、按順序地執行,不會被其餘命令打擾。
    • 原子操做:事務中的命令要麼所有被執行,要麼所有都不執行。
    • 開啓一個事務:

      multi

      之後執行的全部命令,都在這個事務中執行的。

    • 執行事務:

      exec

      會將在multiexec中的操做一併提交。

    • 取消事務:

      discard

      會將multi後的全部命令取消。

    • 監視一個或者多個key

      watch key...

      監視一個(或多個)key,若是在事務執行以前這個(或這些) key被其餘命令所改動,那麼事務將被打斷。

    • 取消全部key的監視:

      unwatch
  13. 發佈/訂閱操做:

    • 給某個頻道發佈消息:
      publish channel message
    • 訂閱某個頻道的消息:
       subscribe channel 
 

第二節:Scrapy-Redis分佈式爬蟲組件

Scrapy是一個框架,他自己是不支持分佈式的。若是咱們想要作分佈式的爬蟲,就須要藉助一個組件叫作Scrapy-Redis,這個組件正是利用了Redis能夠分佈式的功能,集成到Scrapy框架中,使得爬蟲能夠進行分佈式。能夠充分的利用資源(多個ip、更多帶寬、同步爬取)來提升爬蟲的爬行效率。

分佈式爬蟲的優勢:

  1. 能夠充分利用多臺機器的帶寬。
  2. 能夠充分利用多臺機器的ip地址。
  3. 多臺機器作,爬取效率更高。

分佈式爬蟲必需要解決的問題:

  1. 分佈式爬蟲是好幾臺機器在同時運行,如何保證不一樣的機器爬取頁面的時候不會出現重複爬取的問題。
  2. 一樣,分佈式爬蟲在不一樣的機器上運行,在把數據爬完後如何保證保存在同一個地方。

安裝:

經過pip install scrapy-redis便可安裝。

Scrapy-Redis架構:

Scrapy架構圖:

Scrapy-Redis架構圖:

分佈式爬蟲架構圖:

以上兩個圖片對比咱們能夠發現。Item Pipeline在接收到數據後發送給了RedisScheduler調度器調度數據也是從Redis中來的、而且其實數據去重也是在Redis中作的。

編寫Scrapy-Redis分佈式爬蟲:

要將一個Scrapy項目變成一個Scrapy-redis項目只需修改如下三點就能夠了:

  1. 將爬蟲的類從scrapy.Spider變成scrapy_redis.spiders.RedisSpider;或者是從scrapy.CrawlSpider變成scrapy_redis.spiders.RedisCrawlSpider
  2. 將爬蟲中的start_urls刪掉。增長一個redis_key="xxx"。這個redis_key是爲了之後在redis中控制爬蟲啓動的。爬蟲的第一個url,就是在redis中經過這個發送出去的。
  3. 在配置文件中增長以下配置:
# Scrapy-Redis相關配置 # 確保request存儲到redis中 SCHEDULER = "scrapy_redis.scheduler.Scheduler" # 確保全部爬蟲共享相同的去重指紋 DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter" # 設置redis爲item pipeline ITEM_PIPELINES = { 'scrapy_redis.pipelines.RedisPipeline': 300 } # 在redis中保持scrapy-redis用到的隊列,不會清理redis中的隊列,從而能夠實現暫停和恢復的功能。 SCHEDULER_PERSIST = True # 設置鏈接redis信息 REDIS_HOST = '127.0.0.1' REDIS_PORT = 6379 
  1. 運行爬蟲:
    1. 在爬蟲服務器上。進入爬蟲文件所在的路徑,而後輸入命令:scrapy runspider [爬蟲名字]
    2. Redis服務器上,推入一個開始的url連接:redis-cli> lpush [redis_key] start_url開始爬取。
相關文章
相關標籤/搜索