scrapy 中间件

在 Sun 20 December 2015 发布于 源码分析, scrapy 分类 • 标签为 scrapy, Middlewares

Scrapy框架提供的中间件共有两个:Downloader middlewaresSpider Middlewares。这两个中间件分别作用在不同的数据流向上。

Downloader middlewares

Downloader middlewares顾名思义就是下载中间件,该中间件会在Scrapy的引擎从调度器获取到下一个要爬去的Request,并转发给下载器进行下载这个中间过程进行调用。以及下载器把需要爬取的Request爬取后生成的Response对象返回给Scrapy的引擎的过程中会调用Downloader middlewares

管理Downloader middlewares的类是scrapy.middleware.DownloaderMiddlewares对象。该对象在生成Scrapy的下载器的时候会被调用,该对象通过 读取配置文件中DOWNLOADER_MIDDLEWARES来构建该对象。

class DownloaderMiddlewareManager(MiddlewareManager):

  component_name = 'downloader middleware'

  @classmethod
  def _get_mwlist_from_settings …

阅读全文

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 …

阅读全文