我是python的新手,甚至更新的扭曲。我正在尝试使用twisted来下载几十万个文件但是我在尝试添加错误时遇到了麻烦。如果下载失败,我想打印坏网址。我故意拼错了我的一个网址,以便抛出错误。但是,我刚刚挂起的代码并且python没有完成(如果我删除了errback调用它就完成了)。
另外,如何单独处理每个文件?根据我的理解,当一切都完成时,就会调用“完成”。我想在下载文件时对每个文件进行gzip,以便将其从内存中删除。
这就是我所拥有的:
urls = [
'http://www.python.org',
'http://stackfsdfsdfdsoverflow.com', # misspelled on purpose to generate an error
'http://www.twistedmatrix.com',
'http://www.google.com',
'http://launchpad.net',
'http://github.com',
'http://bitbucket.org',
]
def finish(results):
for result in results:
print 'GOT PAGE', len(result), 'bytes'
reactor.stop()
def print_badurls(err):
print err # how do I just print the bad url????????
waiting = [client.getPage(url) for url in urls]
defer.gatherResults(waiting).addCallback(finish).addErrback(print_badurls)
reactor.run()
答案 0 :(得分:2)
欢迎使用Python和Twisted!
您粘贴的代码存在一些问题。我会一次一个地浏览它们。
首先,如果您确实要下载数千个网址,并且urls
列表中有数千个项目,那么这一行:
waiting = [client.getPage(url) for url in urls]
会导致问题。您想尝试同时下载列表中的每个页面吗?默认情况下,通常,您在Twisted中执行的操作会同时发生,因此此循环会立即开始下载urls
列表中的每个URL。最有可能的是,这不会起作用。您的DNS服务器将丢弃一些域查找请求,您的DNS客户端将删除一些域查找响应。 TCP连接尝试任何你回来的地址将争夺任何仍然可用的网络资源,其中一些将超时。其余的连接都会涓涓细流,在几十个或几百个不同的下载之间共享可用带宽。
相反,您可能希望一次将并发度限制为10或20次。我前一段时间在博客上写过one approach to this。
其次,gatherResults
会返回一个Deferred
,只要传递给它的一个 Deferred
发生故障,就会触发client.getPage(url)
。因此,只要任何一个Deferred
失败 - 可能是因为我上面提到的一个问题,或者可能是因为域已经过期,或者Web服务器正在崩溃,或者仅仅是因为一个不幸的瞬态网络状况,gatherResults
返回的finish
将失败。系统会跳过print_badurls
,系统会调用getPage
,错误描述单个失败的Deferred
电话。
要处理来自单个HTTP请求的失败,请将回调和错误添加到getPage
调用返回的defer.gatherResults
。添加这些回调和错误后,您可以使用{{1}}等待下载结果的所有下载和处理完成。
第三,你可能想考虑使用更高级别的工具 - scrapy是一个网络爬行框架(基于Twisted),为这种应用程序提供了许多很酷的实用帮助。