每次yield item都会遍历所有管道么?
比如在parse里想从数据库中查询一下某个id是否存在,根据结果进行下一步,而这时item里的值不适合其他管道。
再比如商品封面图片,商品详情图片需要存入不同的数据库字段,这两者应当用不同的管道来下载,有时只需要下载封面不需要详情图片。
我目前能想到的办法是用item['msg']来记录自己准备干嘛,
item['msg']='check_cover_exist'
yield item
if item['msg'] =='cover_exist':
#经数据库查询封面文件md5值已存在,不爬取详情页
else:
#封面不存在,爬取详情页
在管道里加入下面的代码来判断该管道的职责
if item['msg'] != 'check_cover_exist':
return item
...
#经检查封面存在后
item['msg']='cover_exist'
return item
但我不知该加在哪个方法里,特别是对于下载图片的管道。
----------
经过调式我发现这种情况似乎只能用同步代码,不能用yield,上面的if item['msg'] =='cover_exist':无法得到预期的结果,因为我发现图片管道ImagesPipeline接收到item只是生成了get_media_requests()请求,并没有立刻去发送请求,直到item_completed()才能去判断上文中的封面文件md5是否已在数据库中存在,而这时的代码连详情页都已经爬过了。
带你彻底掌握Scrapy,用Django+Elasticsearch搭建搜索引擎
了解课程