当前位置: 首页 > 面试题库 >

在Celery任务中运行Scrapy Spider

宗增
2023-03-14
问题内容

我有一个Django站点,当用户请求时会发生刮擦,并且我的代码在新过程中启动了Scrapy Spider独立脚本。自然,这与增加用户数量无关。

像这样:

class StandAloneSpider(Spider):
    #a regular spider

settings.overrides['LOG_ENABLED'] = True
#more settings can be changed...

crawler = CrawlerProcess( settings )
crawler.install()
crawler.configure()

spider = StandAloneSpider()

crawler.crawl( spider )
crawler.start()

我决定使用Celery并使用工作人员将爬网请求排队。

但是,我遇到了无法重新启动龙卷风反应堆的问题。第一个蜘蛛和第二个蜘蛛成功运行,但随后的蜘蛛将引发ReactorNotRestartable错误。

任何人都可以在Celery框架中运行Spiders分享任何技巧?


问题答案:

好的,这就是我如何使Scrapy与我的Django项目一起工作的,该项目使用Celery排队要爬网的内容。实际的解决方法主要来自位于http://snippets.scrapy.org/snippets/13/的joehillen的代码。

首先tasks.py文件

from celery import task

@task()
def crawl_domain(domain_pk):
    from crawl import domain_crawl
    return domain_crawl(domain_pk)

然后crawl.py文件

from multiprocessing import Process
from scrapy.crawler import CrawlerProcess
from scrapy.conf import settings
from spider import DomainSpider
from models import Domain

class DomainCrawlerScript():

    def __init__(self):
        self.crawler = CrawlerProcess(settings)
        self.crawler.install()
        self.crawler.configure()

    def _crawl(self, domain_pk):
        domain = Domain.objects.get(
            pk = domain_pk,
        )
        urls = []
        for page in domain.pages.all():
            urls.append(page.url())
        self.crawler.crawl(DomainSpider(urls))
        self.crawler.start()
        self.crawler.stop()

    def crawl(self, domain_pk):
        p = Process(target=self._crawl, args=[domain_pk])
        p.start()
        p.join()

crawler = DomainCrawlerScript()

def domain_crawl(domain_pk):
    crawler.crawl(domain_pk)

这里的窍门是“来自多处理导入过程”,它解决了Twisted框架中的“ ReactorNotRestartable”问题。因此,基本上Celery任务调用
domain_crawl”函数,该函数反复使用“
DomainCrawlerScript”对象来与Scrapy蜘蛛进行交互。(我知道我的示例有点多余,但是我这样做是出于我使用多个版本的python的原因[我的django
Web服务器实际上正在使用python2.4,而我的工作服务器使用了python2.7])


在我的示例中,“ DomainSpider”只是经过修改的Scrapy Spider,它接收URL列表,然后将其设置为“ start_urls”。

希望这可以帮助!



 类似资料:
  • 问题内容: 我使用celery更新新闻聚合站点中的RSS feed。我为每个提要使用一个@task,看起来一切正常。 有一个细节我不确定如何处理:所有提要每分钟都使用@periodic_task更新一次,但是如果提要仍在启动新任务时从上一个定期任务更新,该怎么办?(例如,如果Feed确实很慢或离线,并且任务在重试循环中进行) 目前,我存储任务结果并按以下方式检查其状态: 也许我错过了一些使用芹菜机

  • 问题内容: 我有一个python celery-redis队列处理一次上传和下载值得一次演出和大量演出的数据。 很少有上传内容需要花费几个小时的时间。但是,一旦完成了这样的任务,我就目睹了这种奇怪的芹菜行为:芹菜调度程序通过将其再次发送给工作人员来重新运行刚刚完成的任务(我正在运行一个工作人员),并且它在同一时间发生了2次任务! 有人可以帮助我知道为什么会发生这种情况以及如何预防吗? 这些任务肯定

  • 问题内容: 问题 我已经将一个长期运行的任务划分为多个逻辑子任务,因此我可以在每个子任务完成时报告结果。但是,我正在尝试报告将永远无法完成的任务的结果(而不是不断产生价值),并且正在使用现有的解决方案来做到这一点。 背景 我正在为我编写的某些Python程序构建Web界面。用户可以通过Web表单提交作业,然后返回查看该作业的进度。 假设我有两个函数,每个函数都可以通过单独的形式进行访问: :执行大

  • 问题内容: 我一直在阅读文档并进行搜索,但似乎找不到直接的答案: 你可以取消已经执行的任务吗?(由于任务已开始,需要一段时间,因此需要取消一半) 我是从Celery FAQ的文档中找到的 但是我不清楚这是否会取消排队的任务,或者是否会杀死工作程序上正在运行的进程。感谢你能摆脱的光芒! 问题答案: 撤销将取消任务执行。如果任务被吊销,工人将忽略该任务并且不执行它。如果你不使用持久撤销,则可以在wor

  • 问题内容: 我正在使用celery将任务发送到远程服务器,并试图将结果恢复。使用远程服务器上的update_state方法不断更新任务状态。 我正在使用发送任务 获得celery任务的结果是一个阻塞的呼叫,我不希望我的django应用程序等待结果和超时。 所以我尝试运行另一个celery任务以获取结果。 但这会导致以下错误。 有没有解决此错误的方法。是否需要运行守护进程来获取结果? 问题答案: 使

  • 问题内容: 如何检查一项任务是否在celery中运行(特别是我在使用celery-django)? 我已经阅读了文档,并且已经在Google上进行了搜索,但是看不到类似以下的呼叫: 我的用例是我有一个外部(java)服务来进行代码转换。当我发送要进行代码转换的文档时,我想检查运行该服务的任务是否正在运行,如果没有运行,请(重新)启动它。 我相信我使用的是当前的稳定版本2.4。 问题答案: 每个对象