首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >每allowed_domains刮集深度限值

每allowed_domains刮集深度限值
EN

Stack Overflow用户
提问于 2015-01-06 19:40:00
回答 1查看 9.9K关注 0票数 9

我正在爬行6个不同的allowed_domains,并希望限制一个领域的深度。我该如何限制1域的深度?或者,是否可能只抓取一个离地域的一个深度?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-01-07 02:21:25

刮痕不能提供像这样的东西。您可以每蜘蛛,但不是每个域.

我们能做什么呢?读代码,喝咖啡并解决它(秩序是很重要的)。

其想法是禁用Scrapy的内置DepthMiddleware提供我们的定制服务

首先,让我们定义设置:

  • DOMAIN_DEPTHS将是一个每个域都有深度限制的字典。
  • 如果没有配置域,我们将将DEPTH_LIMIT设置保留为默认设置

示例设置:

代码语言:javascript
复制
DOMAIN_DEPTHS = {'amazon.com': 1, 'homedepot.com': 4}
DEPTH_LIMIT = 3

好了,现在是定制中间件(基于DepthMiddleware):

代码语言:javascript
复制
from scrapy import log
from scrapy.http import Request
import tldextract


class DomainDepthMiddleware(object):
    def __init__(self, domain_depths, default_depth):
        self.domain_depths = domain_depths
        self.default_depth = default_depth

    @classmethod
    def from_crawler(cls, crawler):
        settings = crawler.settings
        domain_depths = settings.getdict('DOMAIN_DEPTHS', default={})
        default_depth = settings.getint('DEPTH_LIMIT', 1)

        return cls(domain_depths, default_depth)

    def process_spider_output(self, response, result, spider):
        def _filter(request):
            if isinstance(request, Request):
                # get max depth per domain
                domain = tldextract.extract(request.url).registered_domain
                maxdepth = self.domain_depths.get(domain, self.default_depth)

                depth = response.meta.get('depth', 0) + 1
                request.meta['depth'] = depth

                if maxdepth and depth > maxdepth:
                    log.msg(format="Ignoring link (depth > %(maxdepth)d): %(requrl)s ",
                            level=log.DEBUG, spider=spider,
                            maxdepth=maxdepth, requrl=request.url)
                    return False
            return True

        return (r for r in result or () if _filter(r))

注意,它需要安装tldextract模块(用于从url提取域名):

代码语言:javascript
复制
>>> import tldextract
>>> url = 'http://stackoverflow.com/questions/27805952/scrapy-set-depth-limit-per-allowed-domains'
>>> tldextract.extract(url).registered_domain
'stackoverflow.com'

现在,我们需要关闭默认中间件,并使用我们实现的中间件:

代码语言:javascript
复制
SPIDER_MIDDLEWARES = {
    'myproject.middlewares.DomainDepthMiddleware': 900,
    'scrapy.spidermiddlewares.depth.DepthMiddleware': None
}
票数 21
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27805952

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档