我有一个使用 Scrapy 的相当复杂的多处理程序。它在大约 95% 的情况下都能正常工作,但偶尔我会在 Twisted 遇到导致 DNSLookupError/TCPTimedOutError 的不良站点时收到未处理的异常。
这不是问题,但不幸的是,这些错误导致 Scrapy 跳过 BaseSpider 解析方法,我在其中设置了一个队列来处理响应。由于它跳过了队列,我无法确定哪些 URL 被跳过了。
有没有办法始终确保每个 Scrapy 请求都以该解析方法结束?我所需要的只是一种访问那些失败的响应对象并将它们放入队列的方法。
这是我的蜘蛛代码示例:
class SeerSpider(BaseSpider):
"""Scrapy-based html retrieval system."""
name = "SeerSpider"
def __init__(self, spider_queue, url_list):
self.queue = spider_queue
self.allowed_domains = []
self.start_urls = []
for url in url_list:
self.allowed_domains.append(str(urlparse(url).netloc))
self.start_urls.append(url)
super(SeerSpider, self).__init__()
def parse(self, response):
"""Extracts information from each website in start_urls."""
self.queue.put(response)
如您所见,它非常基础。
稍后,队列处理如下:
while True:
response = spider_queue.get()
### DO STUFF HERE ###
results_queue.put(result)
接着...
while True:
try:
result = results_queue.get(True, 60)
except:
print 'HALP', sys.exc_info()
result = ['ERROR']
self.results.append(result)
counter -= 1
if counter <= 0 or self.exit == True:
for process in process_list:
process.terminate()
break
我添加了队列超时作为临时解决方案,因此它不会在等待队列中不存在的项目时无限期挂起。如果我能保证某种响应对象将进入 start_urls 列表中每个 URL 的队列,它将解决我所有的问题。
谢谢