【系列】scrapy启动流程源码分析(6)Downloader下载器

6.Downloader下载器

Downloader包含了从调度器调取url之后到scraper获取返回的网页内容之前的所有步骤,关系到网页如何下载,网络通信/HTTP协议/服务器等一系列知识,是最复杂的一部分内容。

Downloader初始化

在之前Crawler.crawl()创建ExecutionEngine执行引擎的时候,就已经初始化了Downloader对象。此对象在配置中定义,默认为:

scrapy/settings/default_settings.py:

DOWNLOADER = 'scrapy.core.downloader.Downloader'

scrapy/core/downloader/init.py:

class Downloader(object):

    def __init__(self, crawler):
        self.settings = crawler.settings
        self.signals = crawler.signals
        self.slots = {
   }
        self.active = set()
        self.handlers = DownloadHandlers(crawler)
        self.total_concurrency = self.settings.getint('CONCURRENT_REQUESTS')
        self.domain_concurrency = self.settings.getint('CONCURRENT_REQUESTS_PER_DOMAIN')
        self.ip_concurrency = self.settings.getint('CONCURRENT_REQUESTS_PER_IP')
        self.randomize_delay = self.settings.getbool('RANDOMIZE_DOWNLOAD_DELAY')
        self.middleware = DownloaderMiddlewareManager.from_crawler(crawler)
        self._slot_gc_loop = task.LoopingCall(self._slot_gc)
        self._slot_gc_loop.start(60)

关键对象有4个:slots,active,DownloadHandlers,DownloaderMiddlewareManager以及一些配置选项。

Downloader:slots对象

这个slots是一个存储Slot对象的字典,key是request对应的域名,值是一个Slot对象。
Slot对象用来控制一种Request下载请求,通常这种下载请求是对于同一个域名。
这个Slot对象还控制了访问这个域名的并发度,下载延迟控制,随机延时等,主要是为了控制对一个域名的访问策略,一定程度上避免流量过大被封IP。

scrapy/core/downloader/init.py#Downloader:

    def _get_slot(self, request, spider):
        key = self._get_slot_key(request, spider)
        if key not in self.slots:
            conc = self.ip_concurrency if self.ip_concurrency else self.domain_concurrency
            conc, delay = _get_concurrency_delay(conc, spider, self.settings)
            self.slots[key] = Slot(conc, delay, self.randomize_delay)

        return key, self.slots[key]
        
    def _get_slot_key(self, request, spider):
        if 'download_slot' in request.meta:
            return request.meta['download_slot']

        key = urlparse_cached(request).hostname or ''
        if self.ip_concurrency:
            key = dnscache.get(key, key)

        return key

对于一个request,先调用’_get_slot_key’获取request对应的key,’_get_slot_key’函数中,可以通过给request的meta中添加’download_slot’来控制request的key值,这样增加了灵活性。如果没有定制request的key,则key值来源于request要访问的域名。
另外对于request对应的域名也增加了缓存机制:urlparse_cached,dnscahe。
同时也通过slots集合达到了缓存的目的,对于同一个域名的访问策略可以通过slots获取而不用每次都解析配置。
然后根据key从slots里取对应的Slot对象,如果还没有,则构造一个新的对象。

这个Slot对象有3个参数,并发度,延迟时间和随机延迟。

Downloader:active对象

active是一个活动集合,用于记录当前正在下载的request集合。

Downloader:DownloadHandlers对象

是一个DownloadHandlers对象,它控制了许多handlers,对于不同的下载协议使用不同的handlers。

默认支持handlers如下:
scrapy/settings/default_settings.py:

DOWNLOAD_HANDLERS_BASE = {
   
    'data': 'scrapy.core.downloader.handlers.datauri.DataURIDownloadHandler',
    'file': 'scrapy.core.downloader.handlers.file.FileDownloadHandler',
    'http': 'scrapy.core.downloader.handlers.http.HTTPDownloadHandler',
    'http
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值