scrapy仅遵循一个深度的外部链接

时间:2017-09-21 10:48:31

标签: python scrapy web-crawler

想象一下,我正在抓取foo.com。 foo.com有几个内部链接,它有一些外部链接,如:

foo.com/hello
foo.com/contact
bar.com
holla.com

我希望scrapy能够抓取所有内部链接,但也只有一个深度用于外部链接,例如我希望scrapy转到bar.comholla.com,但我不希望它转到任何其他链接在bar.com内,所以只有一个深度。

这可能吗?这种情况的配置是什么?

感谢。

3 个答案:

答案 0 :(得分:1)

您可以将蜘蛛基于CrawlSpider课程,并使用已实施Rule方法的process_links,并将其传递给Rule。该方法将在跟踪之前过滤不需要的链接。来自documentation

  

process_links是一个可调用的或一个字符串(在这种情况下,将使用来自具有该名称的蜘蛛对象的方法),将使用指定的{{从每个响应中提取的每个链接列表调用该字符串。 1}}。这主要用于过滤目的。

答案 1 :(得分:0)

不是内置解决方案,但我相信您必须自己中断递归。你可以通过在蜘蛛中保留一组(一组)域并中断或忽略来轻松实现这一点。

某种东西:

from urllib.parse import urlparse

self.track = set()

...
domain = tracktraurlparse(response.url).netloc
x.add(domain)
if len(x) > MAX_RECURSION:
   x.remove(domain)
   # raise StopIteration (# if you're within a generator)
   return None

答案 2 :(得分:0)

我通过将参数传递给回调函数找到了解决方案。如果url是内部链接,我将flag设置为true(否则为false)。如果flag返回false(外部链接),则爬网程序不会提取新链接。这是我的示例代码:

class BrokenLinksSpider(CrawlSpider):
name = test
start_urls = "your_url"

def parse(self, response):
    flag = response.meta.get('flag')
    if flag or flag==None:
        extractor = LinkExtractor(deny_domains="")
        links = extractor.extract_links(response)
        for link in links:
            if link.url[:8]=="your_url":
                new_request = Request(link.url, callback=self.parse,meta={'flag': True})
            else:
                new_request = Request(link.url, callback=self.parse,meta={'flag': False})
            yield new_request