碎屑和芹菜`update_state`
Scrapy and celery `update_state`
我有以下设置 (Docker):
- Celery 链接到 Flask 设置,运行Scrapy 蜘蛛
- Flask 设置(显然)
- Flask 安装程序收到 Scrapy 请求 -> 启动 worker 做一些工作
现在我想根据 celery worker 的进度更新原始的 flask 设置。 但是 现在无法在抓取器内部使用 celery.update_state()
因为它无法访问原始任务(尽管它在 运行 内部芹菜任务)。
顺便说一句:我是否遗漏了一些关于 scrapy 结构的信息?我可以在 __init__
内部分配参数以便能够使用 furtheron 似乎是合理的,但是 scrapy 似乎将该方法用作 lambda 函数..
回答一些问题:
How are you using celery with scrapy?
Scrapy 运行在 celery 任务中,而不是在命令行中 运行。我也没有听说过scrapyd
,这是scrapy的子项目吗?我使用远程工作者从 celery/flask 实例内部触发 scrapy,因此它与原始请求实例化的线程不同,它们是单独的 docker 实例。
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()
很抱歉无法确认它是否有效,但一旦我开始测试它,我会在这里报告!我目前无法在这个项目上投入尽可能多的时间:(
如果您认为我可以为您提供更多帮助,请随时与我联系!
干杯,拉米罗
来源:
- CrawlerRunner 爬虫方法:https://doc.scrapy.org/en/latest/topics/api.html#scrapy.crawler.CrawlerRunner.crawlers
- Celery 任务文档:
- Scrapy 信号:https://doc.scrapy.org/en/latest/topics/signals.html#signals
- 运行 scrapy 作为脚本:https://doc.scrapy.org/en/latest/topics/practices.html#run-scrapy-from-a-script
我有以下设置 (Docker):
- Celery 链接到 Flask 设置,运行Scrapy 蜘蛛
- Flask 设置(显然)
- Flask 安装程序收到 Scrapy 请求 -> 启动 worker 做一些工作
现在我想根据 celery worker 的进度更新原始的 flask 设置。 但是 现在无法在抓取器内部使用 celery.update_state()
因为它无法访问原始任务(尽管它在 运行 内部芹菜任务)。
顺便说一句:我是否遗漏了一些关于 scrapy 结构的信息?我可以在 __init__
内部分配参数以便能够使用 furtheron 似乎是合理的,但是 scrapy 似乎将该方法用作 lambda 函数..
回答一些问题:
How are you using celery with scrapy?
Scrapy 运行在 celery 任务中,而不是在命令行中 运行。我也没有听说过scrapyd
,这是scrapy的子项目吗?我使用远程工作者从 celery/flask 实例内部触发 scrapy,因此它与原始请求实例化的线程不同,它们是单独的 docker 实例。
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
)
我不确定你是如何发射你的蜘蛛的,但我遇到了你描述的同样问题。
我的设置是 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()
很抱歉无法确认它是否有效,但一旦我开始测试它,我会在这里报告!我目前无法在这个项目上投入尽可能多的时间:(
如果您认为我可以为您提供更多帮助,请随时与我联系!
干杯,拉米罗
来源:
- CrawlerRunner 爬虫方法:https://doc.scrapy.org/en/latest/topics/api.html#scrapy.crawler.CrawlerRunner.crawlers
- Celery 任务文档:
- Scrapy 信号:https://doc.scrapy.org/en/latest/topics/signals.html#signals
- 运行 scrapy 作为脚本:https://doc.scrapy.org/en/latest/topics/practices.html#run-scrapy-from-a-script