天天看點

Scrapy-Redis簡單使用首先,官方GitHub位址

首先,官方GitHub位址

https://github.com/rmax/scrapy-redis

特征

1。分布式抓取/抓取

您可以啟動共享單個redis隊列的多個spider實例。Y适合廣泛的多域抓取。

2。分布式後處理

Scraped項目被推送到redis排隊,這意味着您可以在共享項目隊列的所需後處理過程中啟動。

3。Scrapy即插即用元件

排程程式+複制過濾器,項目管道,基礎蜘蛛。

使用環境

redis scrapy scrapy-redis 就夠了。

scrapy-redis 分布式爬蟲。多台電腦共同運作,資料儲存在Redis中。確定伺服器端redis開啟了遠端連接配接。

用于提醒自己的(不确定對不對),scrapy-redis伺服器端隻是提供了一個redis伺服器。隻是提供了一個redis伺服器,隻是提供了一個redis伺服器。

是以隻要是要進行爬蟲,那它充當的就是一個slave,但是,一個電腦是可以既是master又是slave的。。。

就爬取讀書網的新聞測試一下吧。官方建議的 http://www.dmoz.org/ 好像關掉了。這個也沒關系,本來這篇部落格就是個人複習使用,有看到的大神覺得哪裡錯了指出來呗。

https://www.dushu.com/

1。開始建立項目。按照基本的scrapy項目那樣建立。

-> scrapy startproject myscrapy_redis
-> scrapy genpider myspider
           

建立完成

2。settings.py檔案修改。将官網的檔案複制到自己的settings.py檔案就好。

# Enables scheduling storing requests queue in redis.
SCHEDULER = "scrapy_redis.scheduler.Scheduler"

# Ensure all spiders share same duplicates filter through redis.
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"

# Default requests serializer is pickle, but it can be changed to any module
# with loads and dumps functions. Note that pickle is not compatible between
# python versions.
# Caveat: In python 3.x, the serializer must return strings keys and support
# bytes as values. Because of this reason the json or msgpack module will not
# work by default. In python 2.x there is no such issue and you can use
# 'json' or 'msgpack' as serializers.
#SCHEDULER_SERIALIZER = "scrapy_redis.picklecompat"

# Don't cleanup redis queues, allows to pause/resume crawls.
#SCHEDULER_PERSIST = True

# Schedule requests using a priority queue. (default)
#SCHEDULER_QUEUE_CLASS = 'scrapy_redis.queue.PriorityQueue'

# Alternative queues.
#SCHEDULER_QUEUE_CLASS = 'scrapy_redis.queue.FifoQueue'
#SCHEDULER_QUEUE_CLASS = 'scrapy_redis.queue.LifoQueue'

# Max idle time to prevent the spider from being closed when distributed crawling.
# This only works if queue class is SpiderQueue or SpiderStack,
# and may also block the same time when your spider start at the first time (because the queue is empty).
#SCHEDULER_IDLE_BEFORE_CLOSE = 10

# Store scraped item in redis for post-processing.
ITEM_PIPELINES = {
    'scrapy_redis.pipelines.RedisPipeline': 300
}

# The item pipeline serializes and stores the items in this redis key.
#REDIS_ITEMS_KEY = '%(spider)s:items'

# The items serializer is by default ScrapyJSONEncoder. You can use any
# importable path to a callable object.
#REDIS_ITEMS_SERIALIZER = 'json.dumps'

# Specify the host and port to use when connecting to Redis (optional).
#REDIS_HOST = 'localhost'
#REDIS_PORT = 6379

# Specify the full Redis URL for connecting (optional).
# If set, this takes precedence over the REDIS_HOST and REDIS_PORT settings.
#REDIS_URL = 'redis://user:[email protected]:9001'

# Custom redis client parameters (i.e.: socket timeout, etc.)
#REDIS_PARAMS  = {}
# Use custom redis client class.
#REDIS_PARAMS['redis_cls'] = 'myproject.RedisClient'

# If True, it uses redis' ``SPOP`` operation. You have to use the ``SADD``
# command to add URLs to the redis queue. This could be useful if you
# want to avoid duplicates in your start urls list and the order of
# processing does not matter.
#REDIS_START_URLS_AS_SET = False

# Default start urls key for RedisSpider and RedisCrawlSpider.
#REDIS_START_URLS_KEY = '%(name)s:start_urls'

# Use other encoding than utf-8 for redis.
#REDIS_ENCODING = 'latin1'
           

沒有被注釋的就三個地方,替換掉了原來的排程器和去重器。采用scrapy-redis的排程器和去重器。然後指定了item管道 RedisPipeline。

3。修改爬蟲檔案。與一般scrapy項目的爬蟲檔案相比。繼承的類發生了改變

import scrapy
from scrapy_redis.spiders import RedisSpider


class MovieinfoSpider(RedisSpider):
    name = 'movieInfo'

    def parse(self, response):

        # 提取下一頁連結   callback為None 繼續在該parse中解析
        next_page = response.xpath("//a[contains(text(), '下一頁')]/@href")
        print(next_page)
        if next_page:   # 如果存在下一頁
            yield scrapy.Request(response.urljoin(next_page.get()))

        # 提取詳情頁 callback 指向解析詳情頁
        news_detail_page_list = response.xpath("//div[contains(@class, 'news-item')]/h3/a")
        for news_detail_page in news_detail_page_list:
            yield response.follow(news_detail_page, callback=self.parse_detail)

    def parse_detail(self, response):
        title = response.xpath("//h1/text()").get()
        print(title)
        yield {'title': title}

           

觀察該檔案,發現少了 start_urls和start_request()函數,沒有了起始任務隊列和請求開始函數。因為是scrapy-redis,任務隊列存放在redis伺服器中,由排程器擷取。

不過此時由于設定中沒有設定連接配接,是連不上redis的,是以啟動不能成功。

4。修改settings.py

關于slave連接配接伺服器的redis,有兩種方式。

(1)REDIS_HOST表示ip位址 REDIS_PORT表示端口号,去掉注釋将位址端口号修改成自己的即可。

REDIS_HOST = '192.168.0.104'
REDIS_PORT = 6379
           

(2)#REDIS_URL = ‘redis://user:[email protected]:9001’ 使用者名密碼 ip端口,可以将這一行注釋去掉修改成自己的, 比如

REDIS_URL = 'redis://192.168.0.104:6379'
           

方式2 如果設定了 會替換掉方式1的設定。。。

排程器從redis伺服器中取請求,管道向redis存資料時。使用的預設key值。

任務隊列的key 爬蟲名:starturls, 比如爬蟲名字是 myspider那麼key就是

myspider:start_urls

# Default start urls key for RedisSpider and RedisCrawlSpider.
#REDIS_START_URLS_KEY = '%(name)s:start_urls'
           

item資料的key 爬蟲名:items 如 myspider:items

# The item pipeline serializes and stores the items in this redis key.
#REDIS_ITEMS_KEY = '%(spider)s:items'
           

注:如果不做修改, 那麼爬蟲檔案運作時,排程器會從redis伺服器中擷取key 為myspider:start_urls的set中值。

5。如果不喜歡預設的key值,可以自己進行替換。

替換方式一, settings中設定。比如直接settings中設定請求隊列的key

REDIS_START_URLS_KEY = 'myspider:start_urls'
           

如此就将預設的key設定成了myspider:start_urls,我沒有改變預設值,如果想改變,可以自行嘗試。item存儲的key也是一樣的。

替換方式二,爬蟲檔案中設定 redis_key屬性。比如,這樣修改了請求隊列的key,至于item存儲的key,好像隻能從settings中修改。

redis_key = 'myspider:start_urls'
           

6。可以将項目部署到不同機器上,隻要能連接配接上伺服器的redis。然後啟動爬蟲。

啟動方式與一般scrapy相同。不同的是,該種方式啟動後會一直運作,排程器會一直監聽redis伺服器的任務隊列keys中是否有元素。

-> scrapy crawl myspider
           
Scrapy-Redis簡單使用首先,官方GitHub位址

啟動了一個虛拟機,和windows下程式一同啟動爬蟲。可以看到,程式一直在等待。因為初始時,我們的根本就沒有該key值,可以用redis-cli連接配接redis伺服器,放入一個初始值。myspider:start_urls 就是一個key

redis-cli->lpush myspider:start_urls https://www.dushu.com/news/
           
Scrapy-Redis簡單使用首先,官方GitHub位址
Scrapy-Redis簡單使用首先,官方GitHub位址

7。運作過程中 可以中斷運作,而在此啟動時,會繼續擷取值,且不會有重複。

Scrapy-Redis簡單使用首先,官方GitHub位址

第一個就是查重的,每個請求都會生成一個唯一序列字元串辨別,當再次受到該請求,發現redis庫中已存在該辨別,就不再發送該請求。

第二個就是已經存儲的item

第三個是帶請求的request隊列

(看官方文檔還是其他部落格)似乎說有四個key,這個 我就不清楚了,但是三個key應該也可以解釋去重 排程 item管道了。

8。繼續運作。。。直到停止(并不是指程式運作結束,而是長時間沒有擷取新請求)。

其實如果沒出錯 最後redis中存儲的資料數量挺有意思的。。。

120個item,正好是 15*8頁, 而去重的清單有127條資料。。。也就是說,除了初始的請求沒有生成序列,其他的每個網頁請求都生成了一個唯一辨別。。。

這算數應該會算吧。。。