从Python脚本中调用Scrapy未创建JSON输出文件

3
这是我用来调用Scrapy的Python脚本,答案在这里:从脚本中调用Scrapy爬取后总是阻塞脚本执行
def stop_reactor():
    reactor.stop()
dispatcher.connect(stop_reactor, signal=signals.spider_closed)
spider = MySpider(start_url='abc')
crawler = Crawler(Settings())
crawler.configure()
crawler.crawl(spider)
crawler.start()
log.start()
log.msg('Running reactor...')
reactor.run()  # the script will block here until the spider is closed
log.msg('Reactor stopped.')

这是我的pipelines.py代码

from scrapy import log,signals
from scrapy.contrib.exporter import JsonItemExporter
from scrapy.xlib.pydispatch import dispatcher

class scrapermar11Pipeline(object):


    def __init__(self):
        self.files = {}
        dispatcher.connect(self.spider_opened , signals.spider_opened)
        dispatcher.connect(self.spider_closed , signals.spider_closed)


    def spider_opened(self,spider):
        file = open('links_pipelines.json' ,'wb')
        self.files[spider] = file
        self.exporter = JsonItemExporter(file)
        self.exporter.start_exporting()

    def spider_closed(self,spider):
       self.exporter.finish_exporting()
       file = self.files.pop(spider)
       file.close()

    def process_item(self, item, spider):
        self.exporter.export_item(item)
        log.msg('It reached here')
        return item

这段代码来自于这里。
当我像这样运行爬虫时:

Scrapy :: Issues with JSON export

scrapy crawl MySpider -a start_url='abc'

创建了一个带有预期输出的链接文件。但是当我执行Python脚本时,它并没有创建任何文件,尽管爬虫运行时转储的Scrapy统计数据与上一次运行的相似。我认为Python脚本中存在错误,因为第一次尝试时文件已经被创建。如何使脚本输出文件?

不确定是否有帮助,但是:您尝试使用 crawlerprocess 运行它了吗?(http://stackoverflow.com/questions/9530046/can-i-execute-scrapypython-crawl-outside-the-project-dir 和 https://dev59.com/OVjUa4cB1Zd3GeqPTarC) - alecxe
@AlexanderAfanasiev 两个解决方案都使用了在0.16版本中已经被弃用的scrapy.conf。不过我们仍会尝试使用crawlerprocess。 - Pdksock
请看这个答案:https://dev59.com/rXzaa4cB1Zd3GeqPSaGb#23394143这对我有用。 - davegallant
2个回答

1
这段代码对我有效:

from scrapy import signals, log
from scrapy.xlib.pydispatch import dispatcher
from scrapy.conf import settings
from scrapy.http import Request
from multiprocessing.queues import Queue
from scrapy.crawler import CrawlerProcess
from multiprocessing import Process
# import your spider here
def handleSpiderIdle(spider):
        reactor.stop()
mySettings = {'LOG_ENABLED': True, 'ITEM_PIPELINES': '<name of your project>.pipelines.scrapermar11Pipeline'} 

settings.overrides.update(mySettings)

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

spider = <nameofyourspider>(domain="") # create a spider ourselves
crawlerProcess.crawl(spider) # add it to spiders pool

dispatcher.connect(handleSpiderIdle, signals.spider_idle) # use this if you need to handle idle event (restart spider?)

log.start() # depends on LOG_ENABLED
print "Starting crawler."
crawlerProcess.start()
print "Crawler stopped."

-1
一个对我有效的解决方案是放弃运行脚本和使用内部API,改用命令行和GNU Parallel进行并行处理。
要运行所有已知的蜘蛛程序,每个核心一个:
scrapy list | parallel --line-buffer scrapy crawl

scrapy list 命令会将所有爬虫名称逐行列出,允许我们将它们作为参数传递给 GNU Parallel 的命令 (scrapy crawl)。 --line-buffer 表示从进程返回的输出将被混合打印到 stdout 上,但是按行而不是四分之一/半行混在一起(有关其他选项,请查看 --group--ungroup)。

注意:显然,这在具有多个 CPU 核心的机器上效果最佳,因为默认情况下,GNU Parallel 将每个核心运行一个任务。请注意,与许多现代开发机器不同,廉价的 AWS EC2 和 DigitalOcean 层只有一个虚拟 CPU 核心。因此,如果您希望在一个核心上同时运行多个任务,则必须使用 --jobs 参数来调整 GNU Parellel。例如,要在每个核心上运行 2 个 scrapy 爬虫:

scrapy list | parallel --jobs 200% --line-buffer scrapy crawl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接