scrapy 自動終止事件迴圈
阿新 • • 發佈:2018-11-05
from twisted.internet import reactor # 事件迴圈 相當於selecet作用 監聽是否有連線成功(終止條件,所有的socket物件都被移除。) from twisted.web.client import getPage # socket物件(如果下載完成,自動從事件迴圈中移除) from twisted.internet import defer # defer.Deferred 特殊的socket物件(不會發請求,目的是不讓事件迴圈結束,可以手動移除。) # 1、利用getPage建立socket物件 # 2、將socket物件新增到事件迴圈中 # 3、開始事件迴圈(內部發送請求,並接受響應,當所有的socket請求完成後,終止事件迴圈) _close = None count = 0 def response(content): # 回撥函式 print(content) global count count += 1 if count == 3: # 如果發的三個請求都返回了 _close.callback(None) # 手動移除defer.Deferred,讓事件迴圈結束。 # 表示新增到事件迴圈中 @defer.inlineCallbacks#進行非同步處理 def task(): url = 'http://www.baidu.com' # 相當於scrapy中的start_url d = getPage(bytes(url.encode("utf-8"))) # 建立連線 d.addCallback(response) # 添加回調函式#執行回撥函式 類似scrapy 中的callback函式 url = 'https://www.bilibili.com/' # 類似於scrapy中yield Request中的url d = getPage(bytes(url.encode("utf-8"))) d.addCallback(response) # 添加回調函式 url = "https://www.taobao.com/" d = getPage(bytes(url.encode("utf-8"))) d.addCallback(response) # 添加回調函式 global _close _close = defer.Deferred() # 把特殊的socket物件賦值給全域性變數_close yield _close def stop(*args, **kwargs): reactor.stop() spider1 = task() # 開啟socket spider2 = task() # 開啟socket dd = defer.DeferredList([spider1, spider2]) # 把爬蟲放到列表中監聽 dd.addBoth(stop) # 如果socket都完成則呼叫事件迴圈結束的函式 reactor.run() # 開始事件迴圈
注意:addCallback()方法C要大寫
步驟:首先先把task()這個函式放到defer.inlineCallbacks裝飾器進行非同步處理,在task()裡先發請求,執行回撥函式,最後產生出defer.Deferred這種不發請求的特殊socket物件,把task()的返回的物件放入到defer.DeferredList進行監聽,如果當一個socket物件發的所有請求都返回後只剩下defer.Deferred在事件迴圈中,手動把defer.Deferred這個物件移除,defer.DeferredList監聽到事件迴圈為空了,就自動關閉事件迴圈。