Python 在芹菜任务中运行刮擦蜘蛛
我有一个Django站点,当用户请求时,会发生刮擦,我的代码在一个新进程中启动了一个刮擦蜘蛛独立脚本。当然,这并不能满足用户数量的增加 大概是这样的:Python 在芹菜任务中运行刮擦蜘蛛,python,django,scrapy,celery,Python,Django,Scrapy,Celery,我有一个Django站点,当用户请求时,会发生刮擦,我的代码在一个新进程中启动了一个刮擦蜘蛛独立脚本。当然,这并不能满足用户数量的增加 大概是这样的: class StandAloneSpider(Spider): #a regular spider settings.overrides['LOG_ENABLED'] = True #more settings can be changed... crawler = CrawlerProcess( settings ) crawler
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()
我决定用芹菜和工人来排队抓取请求
然而,我遇到了龙卷风反应堆无法重启的问题。第一个和第二个爬行器成功运行,但后续爬行器将抛出ReactorNotRestartable错误
任何人都可以在芹菜框架内与正在运行的爬行器分享任何技巧?好的,下面是我如何在Django项目中使用芹菜排队爬行的过程。实际的解决方法主要来自joehillen的代码(位于此处) 首先是
tasks.py
文件
from celery import task
@task()
def crawl_domain(domain_pk):
from crawl import domain_crawl
return domain_crawl(domain_pk)
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)
然后是crawl.py
文件
from celery import task
@task()
def crawl_domain(domain_pk):
from crawl import domain_crawl
return domain_crawl(domain_pk)
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”问题。因此基本上芹菜任务调用“domain_crawl”函数,该函数反复重用“DomainCrawlerScript”对象,以与您的Scrapy spider接口。(我知道我的示例有点多余,但我之所以这样做是因为我的设置中使用了多个版本的python[我的django Web服务器实际上使用的是python2.4,我的工作服务器使用的是python2.7])
在我这里的示例中,“DomainSpider”只是一个经过修改的Scrapy Spider,它接受一个URL列表,然后将它们设置为“start_URL”
希望这有帮助 我在设置文件中设置为1,这解决了问题。worker守护进程在每次spider运行后启动一个新进程,负责处理反应器。是否使用Postgresql?我从芹菜中得到了最奇怪的“InterfaceError:连接已经关闭”。是的,我正在使用postgresql,如果你想提供错误,我可以尝试帮助你解决,我确实有一个听起来类似的错误,但我不记得它到底是什么,也不记得我做了什么。(我目前正在将11077910个项目加载到我的队列中,我有5台工作机器从中拉出,因此此设置确实有效)我发现了问题,这与在postgres中存储结果有关。我想是这样的:我使用的解决方法是设置芹菜结果后端。你遇到过这个问题吗?是的,你可能是对的,最新版本的芹菜非常棒,所以当我重写这个项目以使用最新版本时,我会让你知道如何解决这个问题well@byoungb我也有同样的问题。此解决方案是否仍适用于scrapy 1.0?你发布的链接现在被破坏了。这是个聪明的主意,不知道芹菜总是重新启动一项任务会有多少开销。但这是有道理的。所以,是的,对于未来的用户,你可能想试试这个。这些设置在最近的芹菜版本中被重命名了。您还可以使用以下标志从命令行应用它:
--max tasks per child 1
当前芹菜4.3.0版的设置名称为WORKER\u max\u tasks\u per\u child
。见文件:&