默認RedisSpider
在啓動時,首先會讀取redis
中的spidername:start_urls
,若是有值則根據url
構建request
對象。html
如今的要求是,根據特定關鍵詞采集。python
例如:目標站點有一個接口,根據post請求參數來返回結果。redis
那麼,在這種狀況下,構建request
主要的變換就是請求體(body),API接口是不變的。shell
對於原來經過url
構建request
的策略就再也不適用了。數據庫
因此,此時咱們須要對相應的方法進行重寫。scrapy
爬蟲類須要繼承至scrapy_redis.spiders.RedisSpideride
我須要從數據庫拿到關鍵詞數據,而後用關鍵詞構建請求。post
此時,咱們將關鍵詞看做start_url
,將關鍵詞push
到redis
中網站
首先,寫一個將單個關鍵詞push
到redis
的方法this
push_data_to_redis
def push_data_to_redis(self, data): """將數據push到redis""" # 序列化,data多是字典 data = pickle.dumps(data) use_set = self.settings.getbool('REDIS_START_URLS_AS_SET', defaults.START_URLS_AS_SET) self.server.spush(self.redis_key, data) if use_set else self.server.lpush(self.redis_key, data)
self.redis_key
若是沒有作任何聲明,則默認爲 spidername:start_urls
接着重寫start_request
def start_requests(self): if self.isproducer(): # get_keywords 從數據庫讀關鍵詞的方法 items = self.get_keywords() for item in items: self.push_data_to_redis(item) return super(DoubanBookMetaSpider, self).start_requests()
上述代碼中有一個self.isproducer
,此方法用於檢測當前程序是否是生產者,即向redis
提供關鍵詞
isproducer
# (...) def __init__(self, *args, **kwargs): self.is_producer = kwargs.pop('producer', None) super(DoubanBookMetaSpider, self).__init__() def isproducer(self): return self.is_producer is not None # (...)
此方法須要配合scrapy命令行使用,例如:
// 啓動一個生產者,producer的參數任意,只要填寫了就是True scrapy crawl myspider -a producer=1 // 啓動一個消費者 scrapy crawl myspider
關於scrapy命令行的更多參數,參考文檔:https://scrapy-chs.readthedocs.io/zh_CN/0.24/topics/shell.html
查看RedisMixin
中的make_request_from_data
方法註釋信息:
Returns a Request instance from data coming from Redis.
根據來源於redis的數據返回一個Request對象
By default,
data
is an encoded URL. You can override this method to
provide your own message decoding.默認狀況下,
data
是已編碼的URL連接。您能夠將此方法重寫爲提供您本身的消息解碼。
def make_request_from_data(self, data): url = bytes_to_str(data, self.redis_encoding) return self.make_requests_from_url(url)
將data
轉爲字符串(網站連接字符串),接着調用了 make_requests_from_url
,經過url
構建request
對象
data
從哪裏來?
查看RedisMixin
的next_request
方法
由此得知,data
是從redis
中pop
出來的,在以前咱們將data
序列化後push
進去,如今pop
出來,咱們將其反序列化並依靠它構建request
對象
重寫make_request_from_data
def make_request_from_data(self, data): data = pickle.loads(data, encoding=self.redis_encoding) return self.make_request_from_book_info(data)
在本例中構建
request
對象的方法是self.make_request_from_book_info
,在實際開發中,根據目標站請求規則編寫構建request
的方法便可。
啓動一個生成者
scrapy crawl myspider -a producer=1
生成者將全部的關鍵詞push完以後,會轉爲消費者開始消費
在多個節點上啓動消費者
scrapy crawl myspider
一個爬蟲的開始,老是根據現有數據採集新的數據,例如,根據列表頁中的詳情頁連接採集詳情頁數據,根據關鍵詞采集搜索結果等等。根據現有數據的不一樣,開始的方法也不一樣,大致還是大同小異的。