scrapy-redis分散式
阿新 • • 發佈:2018-12-11
來自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物件的序列化字串.