gpt4 book ai didi

python - Twisted DeferredList 仅在一半的时间内运行其回调

转载 作者:太空宇宙 更新时间:2023-11-03 19:01:01 24 4
gpt4 key购买 nike

我正在尝试使用 Twisted 制作一个相当简单的网络抓取工具。我让它工作了,但每当我尝试抓取数百个以上的网站时,它就会无限期地挂起,没有明显的原因。一切似乎都正常,除非它在最后停止并留下几个站点需要处理。

我在这里使用了教程:http://technicae.cogitat.io/2008/06/async-batching-with-twisted-walkthrough.html作为蓝图。

这是我的代码:

class Spider:
"""Twisted-based html retrieval system."""

def __init__(self, queue, url_list):
self.process_queue = queue
self.start_urls = []
for url in url_list:
self.start_urls.append(url)

def crawl(self):
"""Extracts information from each website in start_urls."""
deferreds = []
sem = defer.DeferredSemaphore(30)
for url in self.start_urls:
d = sem.run(self._crawl, url, self.process_queue)
deferreds.append(d)
dl = defer.DeferredList(deferreds, consumeErrors=1)
dl.addCallback(self.finish, self.process_queue)
dl.addCallback(self.shutdown)
reactor.run()

def _crawl(self, url, queue):
d = getPage(url, timeout=10)
d.addCallback(self.parse, url, queue)
d.addErrback(self.parse_error, url, queue)
return d

def parse(self, result, url, queue):
print 'Parsing:', url
data = {'body': result, 'url': url}
response = Response(data['url'], data['body'])
queue.put(response)
return data

def parse_error(self, result, url, queue):
print 'Errback from:', url
data = {'body': 'error', 'url': url}
response = Response(data['url'], data['body'])
queue.put(response)
return data

def finish(self, results, queue):
for (valid, data) in results:
if valid:
print 'Success:', data['url']
else:
print 'Failed:', data['url']
finish_signal = Response('FINISHED', 'DONE')
queue.put(finish_signal)

def shutdown(self, ignore):
reactor.stop()

我正在一个更大的程序中运行这部分代码,因此是队列。

对于使 DeferredList 始终触发有什么建议吗?或者关于为什么它只在一半的时候触发,而另一半却毫无异常(exception)地失败的想法?

这非常令人沮丧,特别是因为它可以完美地处理少量 URL(1-100),但在放大时会失败。我是 Twisted 的新手,所以我可能只是搞砸了一些错误返回,但我不知道是什么,或者如何修复它......

此外,在有人回答“使用 Scrapy!”之前我不能使用 Scrapy,原因我不会在这里讨论。假设这个计划是我最后的希望并且必须成功。

编辑:

完整的独立代码,以便人们可以直接运行它:

import sys
from twisted.internet import defer, reactor
from twisted.web.client import getPage

class SeerSpider:
"""Twisted-based html retrieval system."""

def __init__(self, queue, url_list):
self.process_queue = queue
self.start_urls = []
for url in url_list:
self.start_urls.append(url)

def crawl(self):
"""Extracts information from each website in url_list."""
deferreds = []
sem = defer.DeferredSemaphore(30)
for url in self.start_urls:
d = sem.run(self._crawl, url, self.process_queue)
deferreds.append(d)
dl = defer.DeferredList(deferreds, consumeErrors=True)
dl.addCallback(self.finish, self.process_queue)
dl.addCallback(self.shutdown)
reactor.run()

def _crawl(self, url, queue):
d = getPage(url, timeout=10)
d.addCallback(self.parse, url, queue)
d.addErrback(self.parse_error, url, queue)
return d

def parse(self, result, url, queue):
data = {'body': result, 'url': url}
response = Response(data['url'], data['body'])
print response.url
return data

def parse_error(self, result, url, queue):
data = {'body': 'error','url': url}
response = Response(data['url'], data['body'])
print response.url
return data

def finish(self, results, queue):
finish_signal = Response('FINISHED', 'DONE')
print finish_signal.url

def shutdown(self, ignore):
reactor.stop()

class Response:
def __init__(self, url, text):
self.url = url
self.body = text

url_list = ['http://google.com/', 'http://example.com', 'http://facebook.com'] # this will work, make the list bigger to find the bug
spider = SeerSpider(None, url_list)
spider.crawl()

最佳答案

看起来您正在将标准库的多处理库与 Twisted 的使用混合在一起。如果你对此不太小心,随机的东西就会被破坏。例如,也许 react 器在一个进程中满足某些 I/O 事件,而在另一进程中满足其余事件。

但是,很难肯定地说这就是问题所在,因为问题中的示例代码不完整(您可能认为程序的其余部分很无聊,但所有这些无聊的细节综合起来定义了程序的行为,因此它们实际上对您的问题非常重要)。

关于python - Twisted DeferredList 仅在一半的时间内运行其回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16072148/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com