使用抓取工具检查数百个网站和每个网站数百页。
我发现了一个非常大的性能瓶颈。
我为域名设置了延迟,因此我确信抓取工具不会在短时间内向一个网站发送大量请求。
但这是一个问题(至少我认为这是问题):
当蜘蛛从一个域中提取许多网址时,它会使用这些网址填充队列。如果队列末尾的网址数量大于CONCURRENT_REQUESTS
的数量,则蜘蛛最终只会抓取一个网站 - 本网站的网址。
我需要的是能够将来自其他域名的网址排入队列,以便它可以利用它的潜力,并且不必等到一个网站的所有网址都被请求。
我的解决方案:
我认为多个队列可以提供帮助。如果每个域都有单独的请求队列,蜘蛛可以交替排队,不必等待,但我无法弄清楚如何做到这一点。
class MainSpider(CrawlSpider):
name = 'main_spider'
allowed_domains = []
max_depth = 2
example_start_urls = [
'example.com','example2.com','example3.com']
def start_requests(self):
for url in self.example_start_urls:
domain = extract_dom(url)
self.allowed_domains.append(domain)
yield scrapy.Request(url, callback=self.parse_item, meta={'domain': domain, 'depth': 0})
def parse_item(self, response):
depth = response.meta['depth']
d = response.meta['domain']
# DO SOMETHING
if not depth >= self.max_depth:
extractor = LinkExtractor(allow_domains=d.name)
links = extractor.extract_links(response)
for link in links:
yield scrapy.Request(link.url, callback=self.parse_item, meta={'domain': d, 'depth': depth + 1})
示例说明
我们说CONCURENT_REQUESTS
设置为2.如果抓取工具在example1.com
网站和CONCURRENT_REQUESTS_PER_DOMAIN = 1
上找到了20个链接,最终会抓取此网站的urls
一个接一个,因为这个网站有20 urls
排队。而不是这样,蜘蛛可以交替使用example1.com
网址和example2.com
网址,因此这个过程会快两倍。
怎么做?