Scrapy和芹菜`update_state`

时间:2017-06-12 11:48:25

标签: python scrapy celery scrapy-pipeline

我有以下设置(Docker):

  • Celery链接到运行Scrapy蜘蛛的Flask设置
  • Flask设置(显然)
  • Flask设置获取Scrapy请求 - >启动工人做一些工作

现在我希望更新芹菜工人进度的原始烧瓶设置。 但是现在无法在刮刀内部使用celery.update_state(),因为它无法访问原始任务(尽管它在芹菜任务中运行)。

顺便说一句:我是否遗漏了关于scrapy结构的一些事情?我可以在__init__内部分配参数以便能够进一步使用,这似乎是合理的,但scrapy使用该方法作为lambda函数似乎......

回答一些问题:

  • How are you using celery with scrapy? Scrapy在芹菜任务中运行,而不是从命令行运行。我也从未听说过scrapyd,这是一个scrapy的子项目吗?我使用远程工作人员从celery / flask实例内部触发scrapy,因此它与原始请求的线程不同,它们是单独的docker实例。

task.update_state效果很好!在芹菜任务中,但只要我们“进入”蜘蛛,我们就再也无法获得芹菜了。有什么想法吗?

  

从item_scraped信号发出Task.update_state(taskid,meta = {})。如果scrapy恰好在Celery任务本身中运行(因为它默认为self),你也可以在没有taskid的情况下运行。

这类似于访问当前芹菜任务的静态方式吗?我喜欢那样......

2 个答案:

答案 0 :(得分:2)

我不确定你是如何解雇蜘蛛的,但我遇到了你所描述的同样问题。

我的设置是烧瓶作为休息api,根据请求启动芹菜任务启动蜘蛛。我还没有编写代码,但我会告诉你我在想做什么:

from scrapy.settings import Settings
from scrapy.utils.project import get_project_settings
from twisted.internet import reactor
from scrapy.crawler import CrawlerRunner
from scrapy.utils.log import configure_logging
from scrapy import signals
from .your_celery import app



@app.task(bind=True)
def scrapping(self):

    def my_item_scrapped_handler(item, response, spider):
        meta = {
            # fill your state meta as required based on scrapped item, spider, or response object passed as parameters
        }

        # here self refers to the task, so you can call update_state when using bind
        self.update_state(state='PROGRESS',meta=meta)

    settings = get_project_settings()
    configure_logging({'LOG_FORMAT': '%(levelname)s: %(message)s'})

    runner = CrawlerRunner(settings)
    d = runner.crawl(MySpider)
    d.addBoth(lambda _: reactor.stop())

    for crawler in runner.crawlers:
        crawler.signals.connect(my_item_scrapped_handler, signal=signals.item_scraped)


    reactor.run()

我很抱歉无法确认它是否有效,但是一旦我开始测试它,我就会在这里报告!我目前无法为这个项目投入尽可能多的时间:(

如果您认为我可以为您提供更多帮助,请随时与我联系!

干杯,拉米罗

来源:

答案 1 :(得分:1)

需要更多信息才能回答这个问题。

你如何在Scrapy中使用芹菜? scrapy是否在芹菜任务中运行? 如果对你的项目scrapyd有意义,我强烈建议在它自己的服务器下运行scrapy。

如果不是那么是的,item_scraped信号会很好,但前提是您可以访问Celery taskid或Celery任务对象本身。 http://docs.celeryproject.org/en/latest/reference/celery.app.task.html

来自item_scraped信号问题Task.update_state(taskid,meta={})。如果scrapy恰好在Celery任务本身中运行,则也可以在没有taskid的情况下运行(因为它默认为self