我使用Scrapy抓取工具无限期抓取网页,我的脚本使用DEPTH_LIMIT = 0
。
我有两个主要问题:
我的抓取工具会在完全抓取start_urls
中的第一个网站之前关注网站。
抓取工具停留在tumblr
或youtube
这样的大型网站上,并继续抓取数十亿页面。怎么避免这个?我无法列出deny
变量上的每个大网站。
class MyItem(Item):
url = Field()
class HttpbinSpider(CrawlSpider):
name = "expired"
start_urls = ['http://www.siteA.com']
rules = (
Rule(LinkExtractor(allow=('.com', '.fr', '.net', '.org', '.info', '.casino'),
deny=('facebook','amazon', 'wordpress', 'blogspot', 'free', 'reddit', 'videos', 'youtube', 'google', 'doubleclick', 'microsoft', 'yahoo', 'bing', 'znet', 'stackexchang', 'twitter', 'wikipedia', 'creativecommons', 'mediawiki', 'wikidata'),
),
process_request='add_errback',
follow=True),
)
custom_settings = {
'RETRY_ENABLED': True,
'DEPTH_LIMIT' : 0,
'LOG_ENABLED' : True,
'CONCURRENT_REQUESTS_PER_DOMAIN' : 32,
'CONCURRENT_REQUESTS' : 64,
}
def add_errback(self, request):
self.logger.debug("add_errback: patching %r" % request)
return request.replace(errback=self.errback_httpbin)
def errback_httpbin(self, failure):
self.logger.error(repr(failure))
if failure.check(HttpError):
response = failure.value.response
self.logger.error('HttpError on %s', response.url)
elif failure.check(DNSLookupError):
request = failure.request
self.logger.info('Domain expired : %s', request.url)
elif failure.check(TimeoutError):
request = failure.request
self.logger.error('TimeoutError on %s', request.url)
答案 0 :(得分:2)
来自精细的手册:
Scrapy是以广度优先还是深度优先顺序爬行?
默认情况下,Scrapy使用LIFO队列存储待处理的请求, 这基本上意味着它以DFO顺序爬行。这个订单更多 在大多数情况下方便。如果您确实想要以真正的BFO顺序进行爬网, 您可以通过设置以下设置来完成此操作:
DEPTH_PRIORITY = 1
SCHEDULER_DISK_QUEUE =' scrapy.squeues.PickleFifoDiskQueue'
SCHEDULER_MEMORY_QUEUE =' scrapy.squeues.FifoMemoryQueue'