Scrapy框架组件之调度器

在 Fri 06 November 2015 发布于 源码分析 分类 • 标签为 scrapy

本片文章分析的是Scrapy框架的调度器的实现。在Scrapy框架中,调度器的作用是调度Request对象,弹出Request对象提交给Scrapy引擎进行fetch,压入新的需要fetch的Request对象,涉及到Request的存储调度。

在进行下面之前,需要了解一个Python的开源库queuelib, 它现在从Scrapy框架中独立出去,作为一个单独的库开源出去,其实现了一系列的队列。 下面简单的说下:

FifoDiskQueue: 这是个FIFO队列,使用文件块来实现落地磁盘的功能。每个文件块存储的数据的个数为chunksize的大小,这个值默认的情况下是100000条,且在落地的文件夹里面会有个info.json文件,其内容格式为

 {"tail": [0, 0, 0], "head": [10, 0], "chunksize": 100000, "size": 1000000}

size为当前FifoDiskQueue的大小;chunksize为每个文件块能够存储多少条数据;head的第一个元素为要写入数据的文件块的下标,第二个元素为该文件块已经写了多少条数据;tail的第一个元素为要读的文件块的下标,第二个元素为累计读取了多少条数据,第三个元素文件的offset记录读取了多少字节。需要注意的是在每次操作完了FifoDiskQueue实例后,都需要调用其成员函数close,以写入状态到info.json …


阅读全文

scrapy排重机制

在 Wed 16 September 2015 发布于 源码分析 分类 • 标签为 scrapy, Python, 爬虫

本篇文章主要的内容是scrapy在单机排重下的机制, 并提共分布式scrapy爬虫服务的url排重方案

scrapy在单机下设置url是否排重过滤很简单, 在每次抛出对该url构造的Request对象给调度器(schedler)时候, 设置Request的参数dont_filter 是否为True来让schedler判断时候对其走排重过滤的逻辑, dont_filter的默认值为False, 即该url会走排重逻辑 源码逻辑如下:

    def enqueue_request(self, request):
        if not request.dont_filter and self.df.request_seen(request):
            self.df.log(request, self.spider)
            return False
        dqok = self._dqpush(request)
        if dqok:
            self.stats.inc_value('scheduler/enqueued/disk', spider=self.spider)
        else …

阅读全文