【问题标题】:Chain Scrapy Spiders which have data dependencies in a twisted reactorChain Scrapy Spiders 在扭曲的反应器中具有数据依赖性
【发布时间】:2018-02-15 11:21:03
【问题描述】:

实际上,scrapy 文档解释了如何像这样链接两个 spyder

from twisted.internet import reactor, defer
from scrapy.crawler import CrawlerRunner
from scrapy.utils.log import configure_logging

class MySpider1(scrapy.Spider):
    # Your first spider definition
    ...

class MySpider2(scrapy.Spider):
    # Your second spider definition
    ...

configure_logging()
runner = CrawlerRunner()


@defer.inlineCallbacks
def crawl():
    yield runner.crawl(MySpider1)
    yield runner.crawl(MySpider2)
    reactor.stop()

crawl()
reactor.run() # the script will block here until the last crawl call is finished

但在我的用例中,MySpider2 需要使用transformFunction() 转换后由MySpider1 检索的信息。

所以我想要这样的东西:

def transformFunction():
    ... transforme data retrieved by spyder1 ...
    return newdata

def crawl():
    yield runner.crawl(MySpider1)
    newdata = transformFunction()
    yield runner.crawl(MySpider2, data=newData)
    reactor.stop()

我想安排什么:

  1. MySpider1 开始,将data 写入磁盘然后退出
  2. transformFunction()data 转换为 newdata
  3. MySpider2 开始使用newData

那么我如何使用扭曲的反应器和 scrapy 来管理这种行为?

【问题讨论】:

    标签: python asynchronous scrapy twisted yield


    【解决方案1】:

    runner.crawl 返回一个Deferred,因此您可以将回调链接到它。必须对您的代码进行小幅调整。

    from twisted.internet import task
    from scrapy.crawler import CrawlerRunner
    from scrapy.utils.log import configure_logging
    
    configure_logging()
    
    def crawl(reactor):
        runner = CrawlerRunner()
        d = runner.crawl(MySpider1)
        d.addCallback(transformFunction)
        d.addCallback(crawl2, runner)
        return d
    
    def transformFunction(result):
        # crawl doesn't usually return any results if successful so ignore result var here
        # ...
        return newdata
    
    def crawl2(result, runner):
        # result == newdata from transformFunction
        # runner is passed in from crawl()
        return runner.crawl(MySpider2, data=result)
    
    task.react(crawl)
    

    主要功能是crawl(),它由task.react() 执行,它将为您启动和停止反应器。 Deferredrunner.crawl() 返回,transformFunction + crawl2 函数链接到它,以便当一个函数完成时,下一个函数开始。

    【讨论】:

    • 这与问题中的代码并没有什么不同,不是吗?问题已经提出了一个使用inlineCallbacks 来完成这里使用addCallback 完成的实现。那么有什么区别呢?
    • 是的,完全一样 :) 刚刚注意到第二个例子
    • 但不知何故,OP 认为这是一个答案。 :P
    • 对不起,scrapy 的文档中的 inlineCallbacks 和 cie 的区别并不清楚。 Twisted 是另一个需要学习的复杂框架。抱歉,如果这些问题对您来说似乎很容易,但请不要取笑我的错误:/
    猜你喜欢
    • 2018-03-02
    • 2018-08-27
    • 1970-01-01
    • 2017-11-30
    • 2010-12-18
    • 1970-01-01
    • 2013-01-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多