碎屑和芹菜`update_state`

Scrapy and celery `update_state`

我有以下设置 (Docker):

现在我想根据 celery worker 的进度更新原始的 flask 设置。 但是 现在无法在抓取器内部使用 celery.update_state() 因为它无法访问原始任务(尽管它在 运行 内部芹菜任务)。

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


回答一些问题:

task.update_state 效果很好!在 celery 任务中,但是一旦我们成为 'in' 蜘蛛,我们就无法再访问 celery。有什么想法吗?

From the item_scraped signal issue Task.update_state(taskid,meta={}). You can also run without the taskid if scrapy happens to be running in a Celery task itself (as it defaults to self)

这是一种访问当前 celery 任务的静态方式吗?正如我所愿....

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

你如何将芹菜与 Scrapy 一起使用? scrapy 运行ning 是在 celery 任务中吗? 我强烈建议 运行ning scrapy 在它自己的服务器下,如果它对你的项目有意义 scrapyd.

如果不是,那么 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 任务本身中 运行ning(因为它默认为 self

,您也可以 运行 没有 taskid

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

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

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()

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

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

干杯,拉米罗

来源: