in Linux

开源爬虫框架Scrapy

听说Scrapy其实有一段时间了,但只到最近才开始尝试,因为要熟悉整个工具链 (Linux/Python/Vim/Redis…)。

这个框架的特点是结构很清晰。下图为官方文档的架构图,准确的描述了Scrapy内部各组件及数据流。

Scrapy Architecture

Scrapy提供了一个Engine,它的作用是进行Download Jobs的调度,即:

  • Spider是由我们来编写的爬虫业务类,在这里面进行页面的各种解析,并将我们需要抓紧的Url地址封装成Request返回给Engine,由它来进行调度下载
  • 在Request中,我们可以指定希望被执行的callback (回调函数),Engine会将Response做为第一参数传递给callback
  • callback的存在,为Spider提供了无限可能 (你懂的)
  • 如果Spider返回的不是Request而是具体的Item (我们定义的业务实体,它的数据填充来自于解析),Engine 会把它们传送给Item Pipeline,由它来进行处理 (Dump也好,Serialization也好)
  • Scrapy提供了一系列 Downloader MiddleWare (我们也可以自己写),它们可以看成是勾子代码,在特定的Request/Response 事件发生时被回调

通过对架构的窥探,可以了解到如何使用Scrapy:

  • 网络层的Request/Response 调度由系统实现,但我们可以通过settings. py 来影响它的行为
  • 我们需要提供的是 Spider (爬虫解析业务)、Items(业务实体)、ItemPipleline (Item处理),以及辅助的 DB、Exporter、Web services等

Scrapy有非常棒的可调试性,在 Shell 中运行时,会一直有 DEBUG LOG。如果是发布到产品环境,可以配置相应的Telnet Console:

Scrapy LOG information

若要说Scrapy有哪些不足,个人觉得:

  • 所有ItemPipeline是以优先级序列在settings中配置的,对于具体Spider返回的Item,却不可指定特定的Pipeline来处理,这就造成一个Item对应的Pipeline不是排在最高优先级,这个Item的处理周期会被延长
  • Scrapy默认是按 depth-first (深度优先) 进行调度的。这可能会带来的问题:在Spider中如果是子页面被解析到含有别的子页面链接,此时你希望既处理子页面自有Item,又希望Engine处理这些链接,你可能会选择 yield them…… 然后你会发现,Item的进度不理想…… 官方给出了解决方案——或者,你也可以把这两种逻辑拆开成两个Spider,我就是这么干的,效果不错 ^ ^

瑕不掩瑜,以爬虫框架的标准来衡量,Scrapy贵在清晰:去问问做爬虫项目的人,你就能明白清晰有多可贵。

打赏作者
您的支持将激励我继续创作!

您的支持将鼓励我们继续创作!

[微信] 扫描二维码打赏

[支付宝] 扫描二维码打赏

Write a Comment

Comment