2012-10-13 33 views
1
self.agent = Agent(reactor, pool=pool) 
self.deferred = self.agent.request(
      'GET', 
      self.url, 
      Headers({'User-Agent': ['Mozilla/5.0']}) 
     ) 

self.deferred.addCallback(self.gotResponse) 

但是,gotResponse調用了接收數據的每個部分,而不是所有的部分。我可以收集它,但是如何知道我獲得了所有數據?扭曲:如何知道何時收到所有數據?

編輯:

我發現this(來自單詞「如果響應身體已經完全接收」),但仍然不知道如何實現這一點。我的意思是,「失敗會包裹什麼......」是什麼意思?

回答

1

扭曲的文檔提供了一個如何做到這一點的例子。

http://twistedmatrix.com/documents/current/web/howto/client.html

from pprint import pformat 

from twisted.internet import reactor 
from twisted.internet.defer import Deferred 
from twisted.internet.protocol import Protocol 
from twisted.web.client import Agent 
from twisted.web.http_headers import Headers 

class BeginningPrinter(Protocol): 
    def __init__(self, finished): 
     self.finished = finished 
     self.remaining = 1024 * 10 

    def dataReceived(self, bytes): 
     if self.remaining: 
      display = bytes[:self.remaining] 
      print 'Some data received:' 
      print display 
      self.remaining -= len(display) 

    def connectionLost(self, reason): 
     print 'Finished receiving body:', reason.getErrorMessage() 
     self.finished.callback(None) 

agent = Agent(reactor) 
d = agent.request(
    'GET', 
    'http://example.com/', 
    Headers({'User-Agent': ['Twisted Web Client Example']}), 
    None) 

def cbRequest(response): 
    print 'Response version:', response.version 
    print 'Response code:', response.code 
    print 'Response phrase:', response.phrase 
    print 'Response headers:' 
    print pformat(list(response.headers.getAllRawHeaders())) 
    finished = Deferred() 
    response.deliverBody(BeginningPrinter(finished)) 
    return finished 
d.addCallback(cbRequest) 

def cbShutdown(ignored): 
    reactor.stop() 
d.addBoth(cbShutdown) 

reactor.run() 

當請求完成BeginningPrinter的connectionLost()方法將被調用。

Response version: ('HTTP', 1, 0) 
Response code: 302 
Response phrase: Found 
Response headers: 
[('Location', ['http://www.iana.org/domains/example/']), ('Server', ['BigIP'])] 
Finished receiving body: Response body fully received 

看起來檢查if reason.check(twisted.web.client.ResponseDone)會告訴你它是否成功。

+1

您應該使用'reason.check(someType)'而不是'reason.type == someType'。前者尊重繼承層次結構,就像'except'語句一樣。此外,'ResponseDone'的專有名稱是twisted.web.client。ResponseDone',而不是'twisted.web._newclient.ResponseDone'。通常,具有以'_'開頭的組件的名稱是私有的,並且應用程序不應該使用它們。 –

+0

好的,我完全錯過了下劃線。 –

1

我不夠知識足夠扭曲,給你一個正確的答案......但我可以指出一些好的方向。

使用扭曲延遲您可以創建一系列回調(成功)和errbacks(失敗),當某些事情完成時觸發。

在你的例子 - 我不知道什麼self.agent.request做,或爲什麼它可能會返回部分數據。這聽起來並不完全「正確」 - 但通常我通過阻塞包含在延遲SemaphoreService中的代碼來獲取URL。

但是,根據你的代碼,我想建議兩兩件事:

一個 - 上deferreds讀到這裏http://twistedmatrix.com/documents/current/core/howto/defer.html

b - 你要增加一個errback可處理錯誤的請求。關於「包裝」的文本必須處理這樣一個事實,即「扭曲」不會真正引發錯誤 - 相反,它允許您定義errBack來運行,並且可以在這些錯誤中捕獲錯誤。有人更好的扭曲可以希望更好地解釋這一點 - 但由於延期是異步的,你需要這樣的機制來有效地處理錯誤。

class YourExample(object): 
    def your_example(self): 
     self.agent = Agent(reactor, pool=pool) 
     self.deferred = self.agent.request(
       'GET', 
       self.url, 
       Headers({'User-Agent': ['Mozilla/5.0']}) 
      ) 

     self.deferred.addCallback(self.gotResponse).addErrback(self.gotBadResponse) 

def gotBadResponse(self,raised): 
    """you might have cleanup code here, or mark the url as bad in the database, or something similar""" 
    pass 
2

在扭曲的13.1.0中,您可以使用readBody()。從 http://twistedmatrix.com/documents/13.1.0/api/twisted.web.client.readBody.html,「這是一個助手功能,用於不希望增量接收HTTP響應正文的客戶端。」

您可以在上面的示例中調用readBody(),它處理數據,readBody()返回一個延遲,您將附加的另一個回調函數作爲參數傳遞給另一個回調函數。

HTH, Reshad。