Scrapy following(英)外部链接,仅限一个深度

6ojccjat  于 2022-11-23  发布在  其他
关注(0)|答案(4)|浏览(98)

假设我正在抓取foo.com。foo.com有几个指向自身的内部链接,还有一些外部链接,如:

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

我想抓取所有的内部链接,但也只有一个深度的外部链接,如我想抓取到bar.comholla.com,但我不希望它去任何其他链接bar.com内,所以只有一个深度。
这是可能的吗?2这种情况下的配置是什么?

  • 谢谢-谢谢
vecaoik1

vecaoik11#

您可以将spider建立在CrawlSpider类的基础上,并将Rule与已实现的process_links方法一起使用,该方法将传递给Rule。该方法将在不需要的链接被跟踪之前过滤掉它们。请参阅文档:
process_links是一个可调用项或字符串(在这种情况下,将使用来自具有该名称的蜘蛛对象的方法),将使用指定的link_extractor为从每个响应中提取的每个链接列表调用该字符串。这主要用于过滤目的。

vltsax25

vltsax252#

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

relj7zay3#

不是一个内置的解决方案,但我相信你将不得不自己中断递归。你可以很容易地通过保持一个数组(一组)的域在您的蜘蛛和中断或忽略。
类似的事情:

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
x33g5p2x

x33g5p2x4#

为了补充@mcavdar的答案,响应在response.meta['depth']处有一个Depth属性,可以使用该属性而不必设置任何标志。

class BrokenLinksSpider(CrawlSpider):
    name = test
    start_urls = "your_url"
    MAX_DEPTH = 1 # 2nd level

    def parse(self, response: Response) -> None:
        current_depth = response.meta["depth"]
        if current_depth < self.MAX_DEPTH:
            extractor = LinkExtractor(deny_domains="")
            links = extractor.extract_links(response)
            for link in links:
                yield Request(link.url, callback=self.parse)

相关问题