基于scrapy框架进行爬虫开发,一般的流程如下:
- 设计spider类,在spider类中yield request,并注册回调函数处理response
- 设计item,在spider类的回调函数中通过分析response生成item
- 设计pipeline类,处理生成的item,如保存至文件/保存至数据库/聚合分析等
某些应用场景下,我们可能需要在pipeline中对 item进行进一步处理,比如从中提取新的url进行爬取或者调用restful 微服务等。这就需要在pipeline中重新yield 新的request。
而从scrapy的数据流中可以看到,scrapy的执行引擎只向pipeline发送item数据,并不接收pipeline返回的数据。类似在spider类中直接yield request的方式是行不通的,yield语句会中断所有pipeline的执行
image.png
解决方法
显式调用crawler.engine.crawl(),将新的request发送至执行引擎。
class MyPipeline(object):
def __init__(self, crawler):
self.crawler = crawler
@classmethod
def from_crawler(cls, crawler):
return cls(crawler)
def process_item(self, item, spider):
...
self.crawler.engine.crawl(
Request(
url='someurl',
callback=self.custom_callback,
),
spider,
)
# YES, you can define a method callback inside the same pipeline
def custom_callback(self, response):
...
yield item
网友评论