2014-04-28 101 views
1

我寫了下面的python腳本:問題與downloadPage回調函數

from twisted.internet import defer    
from twisted.web.client import getPage, downloadPage, reactor 
import tempfile 

def success(results): 
    print 'success' 

def error(results): 
    print 'error', results 
    reactor.stop() 

tmpfilename = tempfile.mkstemp() 
downloadPage('http://www.google.com', tmpfilename).addCallback(success).addErrback(error) 

reactor.run() 

而且正在以下錯誤:

Unhandled Error 
Traceback (most recent call last): 
    File "/usr/local/lib/python2.7/site-packages/twisted/python/log.py", line 88, in callWithLogger 
    return callWithContext({"system": lp}, func, *args, **kw) 
    File "/usr/local/lib/python2.7/site-packages/twisted/python/log.py", line 73, in callWithContext 
    return context.call({ILogContext: newCtx}, func, *args, **kw) 
    File "/usr/local/lib/python2.7/site-packages/twisted/python/context.py", line 118, in callWithContext 
    return self.currentContext().callWithContext(ctx, func, *args, **kw) 
    File "/usr/local/lib/python2.7/site-packages/twisted/python/context.py", line 81, in callWithContext 
    return func(*args,**kw) 
--- <exception caught here> --- 
    File "/usr/local/lib/python2.7/site-packages/twisted/internet/selectreactor.py", line 151, in _doReadOrWrite 
    why = getattr(selectable, method)() 
    File "/usr/local/lib/python2.7/site-packages/twisted/internet/tcp.py", line 215, in doRead 
    return self._dataReceived(data) 
    File "/usr/local/lib/python2.7/site-packages/twisted/internet/tcp.py", line 221, in _dataReceived 
    rval = self.protocol.dataReceived(data) 
    File "/usr/local/lib/python2.7/site-packages/twisted/protocols/basic.py", line 578, in dataReceived 
    why = self.rawDataReceived(data) 
    File "/usr/local/lib/python2.7/site-packages/twisted/web/http.py", line 518, in rawDataReceived 
    self.handleResponsePart(data) 
    File "/usr/local/lib/python2.7/site-packages/twisted/web/client.py", line 249, in handleResponsePart 
    self.factory.pagePart(data) 
    File "/usr/local/lib/python2.7/site-packages/twisted/web/client.py", line 504, in pagePart 
    self.file.write(data) 
exceptions.AttributeError: 'tuple' object has no attribute 'write' 
Unhandled Error 
Traceback (most recent call last): 
    File "poc.py", line 16, in <module> 
    reactor.run() 
    File "/usr/local/lib/python2.7/site-packages/twisted/internet/base.py", line 1192, in run 
    self.mainLoop() 
    File "/usr/local/lib/python2.7/site-packages/twisted/internet/base.py", line 1204, in mainLoop 
    self.doIteration(t) 
    File "/usr/local/lib/python2.7/site-packages/twisted/internet/selectreactor.py", line 145, in doSelect 
    _logrun(selectable, _drdw, selectable, method) 
--- <exception caught here> --- 
    File "/usr/local/lib/python2.7/site-packages/twisted/python/log.py", line 88, in callWithLogger 
    return callWithContext({"system": lp}, func, *args, **kw) 
    File "/usr/local/lib/python2.7/site-packages/twisted/python/log.py", line 73, in callWithContext 
    return context.call({ILogContext: newCtx}, func, *args, **kw) 
    File "/usr/local/lib/python2.7/site-packages/twisted/python/context.py", line 118, in callWithContext 
    return self.currentContext().callWithContext(ctx, func, *args, **kw) 
    File "/usr/local/lib/python2.7/site-packages/twisted/python/context.py", line 81, in callWithContext 
    return func(*args,**kw) 
    File "/usr/local/lib/python2.7/site-packages/twisted/internet/selectreactor.py", line 156, in _doReadOrWrite 
    self._disconnectSelectable(selectable, why, method=="doRead") 
    File "/usr/local/lib/python2.7/site-packages/twisted/internet/posixbase.py", line 263, in _disconnectSelectable 
    selectable.connectionLost(failure.Failure(why)) 
    File "/usr/local/lib/python2.7/site-packages/twisted/internet/tcp.py", line 485, in connectionLost 
    self._commonConnection.connectionLost(self, reason) 
    File "/usr/local/lib/python2.7/site-packages/twisted/internet/tcp.py", line 299, in connectionLost 
    protocol.connectionLost(reason) 
    File "/usr/local/lib/python2.7/site-packages/twisted/web/client.py", line 198, in connectionLost 
    http.HTTPClient.connectionLost(self, reason) 
    File "/usr/local/lib/python2.7/site-packages/twisted/web/http.py", line 472, in connectionLost 
    self.handleResponseEnd() 
    File "/usr/local/lib/python2.7/site-packages/twisted/web/client.py", line 258, in handleResponseEnd 
    self.factory.pageEnd() 
    File "/usr/local/lib/python2.7/site-packages/twisted/web/client.py", line 531, in pageEnd 
    self.file.close() 
exceptions.AttributeError: 'tuple' object has no attribute 'close' 

如果我更改URL的東西無效它會拋出正確錯誤回調函數,所以它似乎是成功回調的事情,但我不明白爲什麼。

回答

3

在此之後:

tmpfilename = tempfile.mkstemp() 

tmpfilename值是一個元組(參見docs),但是扭轉期望的文件名或文件對象。

所以,你可以這樣做:

tmpfile = tempfile.mkstemp() 
tmpfilename = tmpfile[1] 
downloadPage('http://www.google.com', tmpfilename).addCallback(success).addErrback(error) 

其中工程。

但是,如果你不需要的文件來堅持,我建議是這樣的:

tmpfile = tempfile.TemporaryFile() 
downloadPage('http://www.google.com', tmpfile).addCallback(success).addErrback(error) 

它使用TemporaryFile()構造讓您使用下載的數據,但是一旦這個過程已經結束,該文件是(所有意圖和目的)永遠不會再被看到。

你可以進一步通過使用上下文管理改善這一點 - 是這樣的:

with tempfile.TemporaryFile() as tmpfile: 
    downloadPage('http://www.google.com', tmpfile).addCallback(success).addErrback(error) 

    # do other stuff with tmpfile 

# code that no longer depends on the existence of tmpfile 
+0

該訣竅非常感謝你,先生。 – Jamesla