【问题标题】:Scrapy Item pipeline for multi spiders多蜘蛛的 Scrapy Item 管道
【发布时间】:2015-11-07 18:44:14
【问题描述】:

我有 2 个蜘蛛并在这里运行它:

from scrapy.crawler import CrawlerProcess
from scrapy.utils.project import get_project_settings

settings = get_project_settings()

process1 = CrawlerProcess(settings)
process1.crawl('spider1')
process1.crawl('spider2')

process1.start()

我希望这些蜘蛛写一个通用文件。

这是管道类:

class FilePipeline(object):

    def __init__(self):
        self.file  = codecs.open('data.txt', 'w', encoding='utf-8')
        self.spiders = []

    def open_spider(self, spider):
        self.spiders.append(spider.name)

    def process_item(self, item, spider):
        line = json.dumps(OrderedDict(item), ensure_ascii=False, sort_keys=False) + "\n"
        self.file.write(line)

        return item

    def spider_closed(self, spider):
        self.spiders.remove(spider.name)
        if len(self.spiders) == 0:
            self.file.close()

但是虽然我没有收到错误消息,但当所有蜘蛛都在公共文件中完成写入时,我的行(项目)比 scrapy 日志少。几行被剪掉了。也许有一些练习可以同时从两个蜘蛛中写入一个文件?

更新:

谢谢大家!) 我是这样实现的:

class FilePipeline1(object):
    lock = threading.Lock()
    datafile = codecs.open('myfile.txt', 'w', encoding='utf-8')

    def __init__(self):
        pass

    def open_spider(self, spider):
        pass

    def process_item(self, item, spider):
        line = json.dumps(OrderedDict(item), ensure_ascii=False, sort_keys=False) + "\n"
        try:
            FilePipeline1.lock.acquire()
            if isinstance(item, VehicleItem):            
                FilePipeline1.datafile.write(line)
        except:
            pass
        finally:
            FilePipeline1.lock.release()

        return item

    def spider_closed(self, spider):
        pass

【问题讨论】:

  • 什么不能正常工作 - 您在解释时是否遇到错误?还是该程序无法按照您的意愿进行操作?将这些详细信息添加到您的问题中。
  • 我没有收到错误消息,但是当所有蜘蛛都以公共文件结尾时,我的行(项目)更少,然后在日志中写入。并剪了几行。也许有一些练习可以同时从两个蜘蛛中写入一个文件?

标签: python scrapy scrapy-pipeline


【解决方案1】:

我同意 A. Abramov 的回答。

这只是我的一个想法。您可以在您选择的数据库中创建两个表,然后在两个蜘蛛完成爬行后合并它们。您必须跟踪日志的进入时间,以便您可以根据收到的时间订购日志。然后,您可以将 db 转储为您想要的任何文件类型。这样,程序在写入文件之前不必等待一个进程完成,并且您不必进行任何多线程编程。

更新:

实际上,根据蜘蛛运行的时间长短,您可以将日志输出和时间存储到字典中。其中时间是键,日志输出是值。这比初始化数据库更容易。然后,您可以按顺序将 dict 转储到您的文件中。

【讨论】:

    【解决方案2】:

    您在单独的线程中拥有的两个蜘蛛同时写入文件。正如past 所说,如果您不注意同步,那 导致诸如线条被切断和其中一些丢失之类的问题。为了做到这一点,您需要同步文件访问并仅写入整个记录/行,或者制定将文件区域分配给不同线程的策略,例如用已知的偏移量和大小重新构建一个文件,默认情况下你没有这些。一般来说,从两个不同的线程同时写入到同一个文件中并不是一种常用的方法,除非你真的知道自己在做什么,否则我不建议你这样做。

    相反,我会分离蜘蛛 IO 函数,并等待一个动作完成,然后再开始另一个 - 考虑到您的线程没有同步,它既可以提高程序的效率,又可以让它工作 :) 如果您想要一个如何在您的上下文中执行此操作的代码示例,只需请求它,我会很乐意提供它。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-04
    • 1970-01-01
    相关资源
    最近更新 更多