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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了scrapy仅遵循一个深度的外部链接相关的知识,希望对你有一定的参考价值。

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

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

我想scrapy抓住所有的内部链接,但也只有一个深度的外部链接,如我想scrapy去bar.comholla.com但我不希望它去bar.com内的任何其他链接所以只有一个深度。

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

谢谢。

答案

你可以将你的蜘蛛基于CrawlSpider类,并使用Rules实现process_links方法,你传递给Rule。该方法将在跟踪之前过滤不需要的链接。来自documentation

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

另一答案

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

某种东西:

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
另一答案

我通过将参数传递给回调函数找到了解决方案。如果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

以上是关于scrapy仅遵循一个深度的外部链接的主要内容,如果未能解决你的问题,请参考以下文章

Scrapy spider cralws每页只有一个链接

scrapy主动退出爬虫的代码片段(python3)

scrapy框架全栈/深度抓取

scrapy按顺序启动多个爬虫代码片段(python3)

如何使用scrapy规则从Wiki演员和电影页面爬行到仅演员和fimlography链接中的链接

如何使用多个 NavHost 片段创建深层链接