當前位置:編程學習大全網 - 源碼下載 - scrapy-redis分布式爬蟲啟動為什麽會等待

scrapy-redis分布式爬蟲啟動為什麽會等待

scrapy-redis所實現的兩種分布式:爬蟲分布式以及item處理分布式。分別是由模塊scheduler和模塊pipelines實現。

壹、Scrapy-redis各個組件介紹

(I) connection.py

負責根據setting中配置實例化redis連接。被dupefilter和scheduler調用,總之涉及到redis存取的都要使用到這個模塊。

(II) dupefilter.py

負責執行requst的去重,實現的很有技巧性,使用redis的set數據結構。但是註意scheduler並不使用其中用於在這個模塊中實現的dupefilter鍵做request的調度,而是使用queue.py模塊中實現的queue。

當request不重復時,將其存入到queue中,調度時將其彈出。

(III)queue.py

其作用如II所述,但是這裏實現了三種方式的queue:

FIFO的SpiderQueue,SpiderPriorityQueue,以及LIFI的SpiderStack。默認使用的是第二中,這也就是出現之前文章中所分析情況的原因(鏈接)。

(IV)pipelines.py

這是是用來實現分布式處理的作用。它將Item存儲在redis中以實現分布式處理。

另外可以發現,同樣是編寫pipelines,在這裏的編碼實現不同於文章(鏈接:)中所分析的情況,由於在這裏需要讀取配置,所以就用到了from_crawler()函數。

(V)scheduler.py

此擴展是對scrapy中自帶的scheduler的替代(在settings的SCHEDULER變量中指出),正是利用此擴展實現crawler的分布式調度。其利用的數據結構來自於queue中實現的數據結構。

scrapy-redis所實現的兩種分布式:爬蟲分布式以及item處理分布式就是由模塊scheduler和模塊pipelines實現。上述其它模塊作為為二者輔助的功能模塊。

(VI)spider.py

設計的這個spider從redis中讀取要爬的url,然後執行爬取,若爬取過程中返回更多的url,那麽繼續進行直至所有的request完成。之後繼續從redis中讀取url,循環這個過程。

二、組件之間的關系

三、scrapy-redis實例分析

(1)?spiders/ ebay_redis.py

classEbayCrawler(RedisMixin,CrawlSpider):

"""Spiderthat reads urls from redis queue (mycrawler:start_urls)."""

name = 'ebay_redis'

redis_key = ' ebay_redis:start_urls'

rules = (

# follow all links

# Rule(SgmlLinkExtractor(),callback='parse_page', follow=True),

Rule(sle(allow=('[^\s]+/itm/', )), callback='parse_item'),

)

#該方法是最關鍵的方法,該方法名以下劃線開頭,建立了和redis的關系

def _set_crawler(self, crawler):

CrawlSpider._set_crawler(self, crawler)

RedisMixin.setup_redis(self)

# 解析sku頁面

defparse_item(self,response):

sel =Selector(response)

base_url =get_base_url(response)

item = EbayphoneItem()

print base_url

item['baseurl'] =[base_url]

item['goodsname'] =sel.xpath("//h1[@id='itemTitle']/text()").extract()

return item

該類繼承了RedisMixin(scrapy_redis/spiders.py中的壹個類)和CrawlSpider,加載配置文件的各項,建立和redis的關聯,同時進行抓取後的解析。關鍵方法為_set_crawler(self, crawler),關鍵屬性是redis_key,該key如果沒有初始化則默認為spider.name:start_urls

_set_crawler()方法是如何被調用的:

scrapy/crawl.py/Crawler:?crawl() ->

scrapy/crawl.py/Crawler:_create_spider () ->

CrawlSpider:from_crawler() –>

scrapy/spiders/Spider:?from_crawler() ->

ebay_redis.py :_set_crawler()

(2)?setting.py

SPIDER_MODULES= ['example.spiders']

NEWSPIDER_MODULE= 'example.spiders'

ITEM_PIPELINES = {

'example.pipelines.ExamplePipeline':300,

#通過配置下面該項RedisPipeline'會將item寫入key為

#spider.name:items的redis的list中,供後面的分布式處理item

'scrapy_redis.pipelines.RedisPipeline':400,

}

SCHEDULER= "scrapy_redis.scheduler.Scheduler"

#不清理redisqueues, 允許暫停或重啟crawls

SCHEDULER_PERSIST= True

SCHEDULER_QUEUE_CLASS= 'scrapy_redis.queue.SpiderPriorityQueue'

#該項僅對queueclass is SpiderQueue or SpiderStack生效,阻止spider被關閉的最大空閑時間

SCHEDULER_IDLE_BEFORE_CLOSE= 10

#連接redis使用

REDIS_HOST = '123.56.184.53'

REDIS_PORT= 6379

(3)?process_items.py:

defmain():

pool =redis.ConnectionPool(host='123.56.184.53', port=6379, db=0)

r = redis.Redis(connection_pool=pool)

while True:

# process queue as FIFO, change `blpop`to `brpop` to process as LIFO

source, data =r.blpop(["ebay_redis:items"])

item = json.loads(data)

try:

print u"Processing: %(name)s<%(link)s>" % item

except KeyError:

print u"Error procesing:%r" % item

if__name__ == '__main__':

main()

該模塊是從redis對應的list中取出item,進行處理,可以運行多個進程分布式處理items

(4)執行過程如下:

首先在redis服務器端打開redis服務:

./redis-server

其次執行

./redis-cli lpush ebaycrawler:start_urls?/sch/Cell-Phones-Smartphones-/9355/i.html

然後運行爬蟲:

scrapy runspiderebay_redis.py

可以執行多個爬蟲,同時對ebay_redis:start_urls中的url進行分布式爬取,爬取後的結果都存入了ebay_redis:items的list中,供後續再次處理

最後可以查看items隊列中的內容

./redis-cli llen ebay_redis:items 可以看到該items中總的個數

  • 上一篇:我想找天財藏金白金版的主圖技術指標和副圖技術指標,請問哪裏有下載?
  • 下一篇:我的世界要怎麽做電梯
  • copyright 2024編程學習大全網