[scrapy]scrapy源码分析--数据是如何处理的
目录
- 下载中间件(Download MiddleWare)是如何加载的
- Spider MiddleWare是如何加载的
- 配置文件是如何起作用的
- 整体的执行流程是怎样的
- 扩展件是如何工作的
- 数据是怎么处理的
分析
我们正常的思路就是从spider的parse方法来着手,因为我们写的最多的代码就是从这里开始的,这样我们直接从scraper.py来看
def call_spider(self, result, request, spider):
result.request = request
dfd = defer_result(result)
dfd.addCallbacks(request.callback or spider.parse, request.errback)
return dfd.addCallback(iterate_spider_output)
这里我就们就可以看到spider如果指定了callback,那callback对应的方法优先级最高,如果没有callback,那就是默认的spider.parse方法,我们来看看谁在调用这个call_spider方法
到最后一步的时候其实已经跨到engine.py了,我们不是经常写yield Request或者yield item这种方法吗?这yield和return 有什么区别呢,不急,我们先看看是怎么处理我们的输出的,先看如下的代码:
def _process_spidermw_output(self, output, request, response, spider):
"""Process each Request/Item (given in the output parameter) returned
from the given spider
"""
if isinstance(output, Request):
self.crawler.engine.crawl(request=output, spider=spider)
elif isinstance(output, (BaseItem, dict)):
self.slot.itemproc_size += 1
dfd = self.itemproc.process_item(output, spider)
dfd.addBoth(self._itemproc_finished, output, response, spider)
return dfd
elif output is None:
pass
else:
typename = type(output).__name__
logger.error('Spider must return Request, BaseItem, dict or None, '
'got %(typename)r in %(request)s',
{'request': request, 'typename': typename},
extra={'spider': spider})
拿到返回的内容之后,先判断是item 还是request,如果是item ,则调用process_item方法-就是我们在pipeline里面的定义的内容,这里被加载进来之后做数据的方法,如果是request类型呢,就放回到队列之中,然后进一步的处理。
我们小小看一步是如何处理的
看看这个_scrape_next方法
def _scrape_next(self, spider, slot):
while slot.queue:
response, request, deferred = slot.next_response_request_deferred()
self._scrape(response, request, spider).chainDeferred(deferred)
信号槽中一直存在队列的时候,那就一直处理直到结束,一直调用_scrape方法。这样整个的流程和逻辑就清晰了.
- 原文作者:大鱼
- 原文链接:https://brucedone.com/archives/870/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议. 进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。