Twisted Python getPage

4

我尝试寻求支持,但我完全感到困惑。

以下是我的代码:


from twisted.internet import reactor
from twisted.web.client import getPage
from twisted.web.error import Error
from twisted.internet.defer import DeferredList
from sys import argv
class GrabPage: def __init__(self, page): self.page = page def start(self, *args): if args == (): # We apparently don't need authentication for this d1 = getPage(self.page) else: if len(args) == 2: # We have our login information d1 = getPage(self.page, headers={"Authorization": " ".join(args)}) else: raise Exception('Missing parameters')
d1.addCallback(self.pageCallback) dl = DeferredList([d1]) d1.addErrback(self.errorHandler) dl.addCallback(self.listCallback)
def errorHandler(self,result): # Bad thingy! pass
def pageCallback(self, result): return result
def listCallback(self, result): print result
a = GrabPage('http://www.google.com') data = a.start() # Not the HTML

当调用start()时,我希望能够获取传递给pageCallback的HTML。这对我来说一直很麻烦。谢谢!对于我的糟糕代码,抱歉。


不是很相关,但我可以知道你为什么要使用Twisted吗? - Anurag Uniyal
1个回答

14

你缺少了Twisted运作的基础知识。这一切都围绕着"反应器(reactor)"展开,而你甚至没有启动它。把反应器想象成这样:

反应器循环
(来源:krondo.com)

在启动反应器之前,只是在链接Deferred对象,没有任何事件可以触发。

我建议你阅读Dave PeticolasTwisted Intro。它很快,而且真正给你提供了Twisted文档中缺失的所有信息。

无论如何,以下是最基本的getPage使用示例:

from twisted.web.client import getPage
from twisted.internet import reactor

url = 'http://aol.com'

def print_and_stop(output):
    print output
    if reactor.running:
       reactor.stop()

if __name__ == '__main__':
    print 'fetching', url
    d = getPage(url)
    d.addCallback(print_and_stop)
    reactor.run()

由于getPage返回一个deferred,因此我将回调函数print_and_stop添加到deferred链中。之后,我启动了reactor。Reactor触发getPage,然后触发print_and_stop,该函数打印来自aol.com的数据,然后停止reactor。

编辑以展示OP代码的工作示例:

class GrabPage:
    def __init__(self, page):
        self.page = page
        ########### I added this:
        self.data = None

    def start(self, *args):
        if args == ():
            # We apparently don't need authentication for this
            d1 = getPage(self.page)
        else:
            if len(args) == 2:
                # We have our login information
                d1 = getPage(self.page, headers={"Authorization": " ".join(args)})
            else:
                raise Exception('Missing parameters')

        d1.addCallback(self.pageCallback)
        dl = DeferredList([d1])
        d1.addErrback(self.errorHandler)
        dl.addCallback(self.listCallback)

    def errorHandler(self,result):
        # Bad thingy!
        pass

    def pageCallback(self, result):
        ########### I added this, to hold the data:
        self.data = result
        return result

    def listCallback(self, result):
        print result
        # Added for effect:
        if reactor.running:
            reactor.stop()

a = GrabPage('http://google.com')
########### Just call it without assigning to data
#data = a.start() # Not the HTML
a.start()

########### I added this:
if not reactor.running:
    reactor.run()

########### Reference the data attribute from the class
data = a.data
print '------REACTOR STOPPED------'
print
########### First 100 characters of a.data:
print '------a.data[:100]------'
print data[:100] 

反应器已经在另一个文件中运行了。这是一个导入的文件。我想我应该提一下这一点。 :x - Dave Dixon
我为您添加了一个简单的示例,希望能帮助您更好地理解它。 - jathanism
我认为这种格式不可行。我也不能让它打印出来。它需要是一个返回值。因为另一个导入会影响到这个结果。 - Dave Dixon
如果需要的话,可以将其更改为返回。我运行了你的代码,它成功地返回了数据。你需要确保如果你需要收集这些数据,那么当回调被触发时,你需要让回调执行该操作。例如,通过在开始工作之前声明一个字典,然后让pageCallback向该字典添加一个键。换句话说,如果你想让a.start()返回html数据,你就必须让该方法return一些东西。 - jathanism
好的。显然我是地球上最瞎的人,因为每个人都说他们可以成功地让它工作。我不知道我需要返回什么以及在哪里找到我需要的数据。 - Dave Dixon
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接