1. 程式人生 > >初識 分散式爬蟲scrapy_redis

初識 分散式爬蟲scrapy_redis

  • 概念 將同一個爬蟲程式放在多臺電腦上(或者同一個電腦中的多個虛擬機器環境),並且在多臺電腦上同時啟動這個爬蟲。一個電腦執行一個爬蟲程式稱為單機爬蟲。
  • 作用 可以利用多臺電腦的頻寬,處理器等資源提高爬蟲的爬取速度
  • 原理 進去佇列是push,出來佇列是pop 在這裡插入圖片描述 在這裡插入圖片描述 分散式需要解決的問題:(共用的佇列Queue和共用的去重集合set(),這兩個是scrapy自身無法解決的問題。只能通過第三方元件。) 1> 需要保證多臺電腦中的爬蟲程式碼完全一致 2> 多臺電腦操作同一個網站,如何管理url去重? scrapy如何做去重的? a). scrapy會將所有的Request物件 (request.url,request.method,request.body)進行加密,生成一個指紋物件fingerprint; b)
    .然後將指紋物件放入set()集合中進行對比,如果set()集合中已經存在這個物件,那麼scrapy就會將這個Request拋棄。如果set()集合中不存在這個指紋物件,就將這個Request新增到排程佇列queue中,等待被排程器排程. 3> 多臺電腦就會有多個set()物件,能否使用各自的set()做去重? 不能。 a) 這個set()物件中的資料都是儲存在電腦記憶體中的,電腦的記憶體空間(執行記憶體)是不能共享的。 b) 這個set()物件隨著程式的啟動而建立,程式的退出而銷燬。所以,要解決這個問題,需要讓所有電腦共用同一個set()集合。不再使用scrapy內建的set()物件,而是使用scrapy-redis將這個set()集合在redis中建立,然後多臺電腦訪問同一個redis就可以實現set集合的共用。 4>
    用於存放合法Request請求物件的佇列,在scrapy中也是預設存在於記憶體中的,也是無法實現多臺電腦的共享佇列。如果是多臺電腦的話,就需要保證多臺電腦有共用的佇列queue,這樣可以保證所有電腦從同一個佇列中獲取Request物件進行排程,所有set()過濾出來的Request都放到同一個佇列中。 所以,要解決這個問題,需要讓所有電腦共用同一個佇列。不再使用scrapy內建的queue,而是使用scrapy-redis將這個queue在redis中建立,然後多臺電腦訪問同一個redis就可以實現queue的共用。 5> 如何將不同電腦上獲取的資料,儲存在同一個資料庫中。
  • 安裝:github官網搜尋:scrapy_redis 在這裡插入圖片描述
    在這裡插入圖片描述 安裝在D盤
  • 配置(以專案jobbolespider為例) 在這裡插入圖片描述 a> (必須配置) # 配置scrapy-redis # Enables scheduling storing requests queue in redis. # 更換scrapy內建排程器檔案,使用scrapy_redis包中的scheduler排程器檔案。 SCHEDULER = "scrapy_redis.scheduler.Scheduler" #Ensure all spiders share same duplicates filter through redis. # 更換scrapy內建的去重檔案,使用scrapy_redis包中的dupefilter檔案。 DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter" 在這裡插入圖片描述 b> (可選配置) #是否將解析出來的item資料在redis中儲存一份。如果需要儲存,就配置這個pipeline。 ITEM_PIPELINES = { 'scrapy_redis.pipelines.RedisPipeline': 300 } c> (必須配置) # 配置REDIS_URL = ‘(redis://redis資料庫使用者(預設是root):redis資料庫連線密碼(預設為空))@(redis的連線地址):(redis的埠號)’ # hostname: redis的連結地址,由於多臺電腦要連線同一個redis資料庫,所以,這個連結地址可以是其中一臺電腦的IP地址。注意:這個IP地址對應的電腦必須啟動redis服務,否則其他電腦無法連結這個IP對應的redis。 # 如果是在阿里雲上購買的redis資料庫伺服器,這個hostname就填寫阿里雲的redis伺服器的公網IP。 REDIS_URL = 'redis://root:@192.168.53.88:6379' d> (必須配置) 在這裡插入圖片描述 配置redis服務,預設redis只支援localhost的本地連線,不允許遠端連線,需要配置redis服務,開啟遠端連線功能。去本地安裝包,找到D:/Redis/redis.windows.conf檔案: 1> 將protected-mode yes這個保護模式關閉,設定為no; 2> 將bind 127.0.0.1修改成REDIS_URL中設定的IP地址(192.168.53.88); 在這裡插入圖片描述 在修改redis.windows.conf配置檔案以後,必須將 “Redis” 服務從計算機-管理中刪除,然後重新根據修改後redis.windows.conf配置檔案進行註冊新的服務,這樣修改的配置檔案才生效。 解除安裝Redis服務sc delete redis 安裝Redis服務redis-server.exe --service-install redis.windows.conf --loglevel verbose 根據修改之後的redis.windows.conf建立一個新的Redis服務redis-server.exe redis.windows.conf 在這裡插入圖片描述

將上面建立的服務最小化,記住不要關閉!!

注意:分散式爬蟲程式中設定的所有的KEY,都是"xxx:xxx"結構,對應的是容器的名稱(類似於MySQL中的表名),並不是容器內容中key:value的這個key。 e> (必須配置) from …scrapy_redis.spiders import RedisSpider class BoleSpider(RedisSpider): name = ‘bole’ allowed_domains = [‘jobbole.com’] # start_urls = [‘http://blog.jobbole.com/all-posts/’] 分散式就不需要再設定起始的url,需要通過redis進行新增起始的url。起始的url新增到哪去了? 被新增到了公共佇列queue中。讓多臺機器中的其中一臺從公共的reids佇列queue中,獲取起始的url,並對這個起始的url進行請求和解析,獲取更多的url,然後將所有的url構造成Request,還放入公共佇列queue中,讓其他機器獲取這些Request請求。 redis_key = ‘jobbole:start_urls’ 在這裡插入圖片描述 如果上面from …scrapy_redis.spiders import RedisSpider出現錯誤,或者執行的時候報錯“No moudle RedisSpider”。解決方法:將第二層jobbolespider改成根目錄即可。 在這裡插入圖片描述 f> 向redis_key = ‘jobbole:start_urls’這個鍵中,新增起始url. lpush jobbole:start_urls http://blog.jobbole.com/all-posts/ 下面,在cmd視窗進行新增起始url 在這裡插入圖片描述 g> 修改MySQL資料庫為遠端連線,讓所有電腦連線同一個資料庫,爬取出來的資料都儲存在同一個資料庫的表中。 預設情況下,MySQL分配的root使用者只允許本地連線localhost,如果需要通過IP建立資料庫的連線,需要建立一個具有遠端連線許可權的使用者: .: 所有連線地址都可以使用,比如:localhost , 192.168.1.121 , 117.56.23.4 rootuser: 新建立的使用者名稱 ‘%’: 表示所有許可權 ‘123456’: 連線密碼 建立一個名稱為 “user” 的使用者,%表示該使用者可以使用任意IP進行連線,identified by是設定密碼。 create user “user”@"%" identified by “123456”; 給名稱為 “user” 的使用者分配所有資料庫的讀寫許可權,*.*表示user可以對任意資料庫都有操作許可權。 GRANT ALL privileges ON . TO ‘user’@’%’; 在這裡插入圖片描述 下面,你就可以把你的專案發給其他的電腦 ,其他的電腦只需要將 d>步驟 的1>配置redis服務,預設redis只支援localhost的本地連線,不允許遠端連線,需要配置redis服務,開啟遠端連線功能。去本地安裝包,找到redis.windows.conf檔案: 1> 將protected-mode yes這個保護模式關閉,設定為no; 即可;其他電腦什麼都不用修改 下面,需要所有的電腦,包括主爬蟲電腦以及其他電腦進行MySQL視覺化工具的連線在這裡插入圖片描述 然後所有進行在debug檔案中進行run即可實現分散式爬蟲。