我有一个网址列表。我希望每隔10秒异步获取一次内容。
urls = [
'http://www.python.org',
'http://stackoverflow.com',
'http://www.twistedmatrix.com',
'http://www.google.com',
'http://launchpad.net',
'http://github.com',
'http://bitbucket.org',
]
waiting = [client.getPage(url) for url in urls]
defer.gatherResults(waiting).addCallback(saveResults)
reactor.run()
我该怎么做?此代码允许我只获取一次网址内容。再次调用它会抛出error.ReactorNotRestartable()
谢谢:)
答案 0 :(得分:2)
使用Twisted绝对可以。
首先,虽然这与您的问题有些不相关,但请勿使用getPage
。它是一个非常有限的API,HTTPS上的安全性默认设置很差。相反,请使用Treq。
现在,关于你的主要问题。
了解reactor.run()
的重要一点是,它并不代表"在这里运行此代码"。这意味着"运行整个程序"。当reactor.run()
退出时,您的程序将退出该时间。
幸运的是,Twisted有一个很好的内置方式来定期做事:LoopingCall
。
以下是一个使用treq
和LoopingCall
的工作示例:
urls = [
'http://www.python.org',
'http://stackoverflow.com',
'http://www.twistedmatrix.com',
'http://www.google.com',
'http://launchpad.net',
'http://github.com',
'http://bitbucket.org',
]
from twisted.internet.task import LoopingCall
from twisted.internet.defer import gatherResults
from treq import get, content
def fetchWebPages():
return (gatherResults([get(url).addCallback(content) for url in urls])
.addCallback(saveResults))
def saveResults(responses):
print("total: {} bytes"
.format(sum(len(response) for response in responses)))
repeatedly = LoopingCall(fetchWebPages)
repeatedly.start(10.0)
from twisted.internet import reactor
reactor.run()
作为奖励,它处理fetchWebPages
花费超过10秒的情况,并且会智能地做出反应,而不是让太多未完成的请求堆积起来,或者随着请求需要更长时间而延迟更长时间。