1. 程式人生 > >scrapy-redis分散式

scrapy-redis分散式

來自scrapy-redis包的知識

前言

scrapy-redis是一個python包, 是scrapy基於redis的一個元件. 用於scrapy爬蟲分散式開發.

在環境配置OK下, 將原有的scrapy專案copy到其他主機上執行就行.

使用該工具需要環境: python3, redis, scrapy.

安裝

window: pip install scrapy-redis

ubuntu: pip3 install scrapy-redis

使用

大致過程: 在多臺主機環境下, spider開始執行在各主機上, spider請求的request和item會發送到redis中的佇列中進行排列和去重, 同時各主機的spider也會從master(即redis所在主機)的redis中取下一步需要請求的request, 就這樣迴圈下去.

要使用scrapy-redis很簡單, 將spider類繼承RedisSpider類, 再設定redis_key(類似start_urls)和settings檔案.

spider設定

# 下面是爬longzhu_app資料的spider程式碼, 改變一下.
# -*- coding: utf-8 -*-
import scrapy
from longzhu.items import LongzhuItem
import json
from urllib.request import urlretrieve
from scrapy_redis.spider import RedisSpider		# 匯入.
# 我們在這繼承RedisSpier類. class BeautySpider(RedisSpider): name = 'beauty' allowed_domains = ['longzhu.com'] #start_urls = ['需要請求的json_url'], 沒做post處理, url太長不放出來了. redis_key = 'longzhu:start_urls' # 最好是這樣的命名方式, project:start_urls basic_url = "http://y.longzhu.com/" image_path = "圖片存放的資料夾" offset = 0
def parse(self, response): datas = json.loads(response.text)['data']['streamFlows'][0]['streams'] for data in datas: item = LongzhuItem() item['room_id'] = data['room']['domain'] item['room_title'] = data['room']['title'] item['room_href'] = self.basic_url + item['room_id'] item['room_one'] = data['user']['name'] item['online_amount'] = data['room']['viewers'] item['follow_amount'] = data['user']['fans_num'] item['one_picture'] = data['cover'] if urlretrieve(item['one_picture'], self.image_path + item['room_one']) is not None: self.offset += 1 print(f"{self.offset} picture is download.") yield item

settings

# 我們需要將下面的幾條配置加入到settings中.
# 1.使用了scrapy_redis的去重元件,在redis資料庫裡做去重
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"

# 2.使用了scrapy_redis的排程器,在redis裡分配請求
SCHEDULER = "scrapy_redis.scheduler.Scheduler"

# 3.在redis中保持scrapy-redis用到的各個佇列,從而True允許暫停和暫停後恢復,也就是不清理redis_queues
# False就是清理. 一般我們設定為True.
SCHEDULER_PERSIST = True

# 4.通過配置RedisPipeline將item寫入key為 spider.name : items 的redis的list中,供後面的分散式處理
# item這個已經由 scrapy-redis 實現,不需要我們寫程式碼,直接使用即可
ITEM_PIPELINES = {
    'scrapy_redis.pipelines.RedisPipeline': 100
}

# 5.指定redis資料庫的連線引數, 資訊為主機的ip和port.
REDIS_HOST = '127.0.0.1'
REDIS_PORT = 6379

在這些設定好了以後, 就可以scrapy runspider spiderfile運行了, 執行後scrapy會進入阻塞狀態, 我們這裡進去redis中, 使用lpush longzhu:start_urls '第一個需要請求的URL'(和spider中的redis_key一樣.), 將url扔到redis中, 阻塞狀態中的scrapy查詢到了就會取這個url開始請求並開始執行, 執行結果會儲存在redis中等待開發者做進一步處理.

result

# 在redis中會出現如下 4 個物件.

"專案名:items" 
list型別,儲存爬蟲獲取到的資料item, 內容是json字串.
	
"專案名:dupefilter"
set型別, 用於爬蟲訪問的URL去重, 內容是40個字元的 url 的hash字串.

"專案名: start_urls"
List型別, 用於獲取spider啟動時爬取的第一個url.

"專案名:requests"
zset型別, 用於scheduler排程處理requests內容是request物件的序列化字串.