2013-03-08 42 views
1

我使用twisted和它的deferredGenerator編寫了一個爬行程序。 以下是關於我的問題代碼:使用扭曲的抓取工具,當getPage出現超時錯誤時我該怎麼辦?

 @defer.deferredGenerator 
     def getReviewsFromPage(self,title,params): 

      def deferred1(page): 
       d = defer.Deferred() 
       reactor.callLater(1,d.callback,self.parseReviewJson(page)) 
       return d 

      def deferred2(dataL,title): 
       d = defer.Deferred() 
       reactor.callLater(1,d.callback,self.writeToCSV(dataL,title=title)) 
       return d 

      cp = 1 
      #for cp in range(1,15000): 
      while self.running: 
       print cp 
       params["currentPageNum"] = cp 

       url = self.generateReviewUrl(self.urlPrefix,params = params) 
       print url 

       wfd = defer.waitForDeferred(getPage(url,timeout=10)) 
       yield wfd 
       page = wfd.getResult() 
       wfd = defer.waitForDeferred(deferred1(page)) 
       yield wfd 
       dataList = wfd.getResult() 
       wfd = defer.waitForDeferred(deferred2(dataList,title)) 
       yield wfd 
       cp = cp+1 

而且我通過

self.getReviewsFromPage(title,params) 
    reactor.run() 

我的問題用發電機是: 當函數「GETPAGE」得到一個超時錯誤,我能做些什麼來處理錯誤並再次抓取錯誤頁面?我添加了一個addErrback來getPage一次,並且想要回顧getPage,但是似乎當reactor運行時,它不會再收到新事件。

你們有沒有發生過同樣的問題?我很感謝你的幫助

回答

2

看來,當反應堆運行時,它不會再收到新的事件。

事實並非如此。事件只有發生在反應堆運行時!

你沒有分享使用addErrback的代碼版本,所以我看不出你是如何使用它的問題。但是,因爲你已經在使用deferredGenerator,更慣用的做法是:

page = None 
for i in range(numRetries): 
    wfd = defer.waitForDeferred(getPage(url,timeout=10)) 
    yield wfd 
    try: 
     page = wfd.getResult() 
    except TimeoutError: 
     # Do nothing, let the loop continue 
     pass 
    else: 
     # Success, exit the loop 
     break 
if page is None: 
    # Handle the timeout for real 
    ... 
else: 
    # Continue processing 
    ... 
+0

謝謝您的回答。我昨天解決了這個問題,並且解決方案與你的非常相似,它是從wfd.getResult獲取頁面並檢查它的類型是否爲NoneType(我不知道該類型是否與errback有任何關係。我添加的函數到errback沒有返回)。你給了一個合適的解決方案謝謝! – user2147650 2013-03-09 12:24:46

相關問題